diff --git a/notebooks/.DS_Store b/notebooks/.DS_Store new file mode 100644 index 00000000..c774ecb1 Binary files /dev/null and b/notebooks/.DS_Store differ diff --git a/notebooks/.ipynb_checkpoints/Deep_dive_into_RAG_evaluation-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/Deep_dive_into_RAG_evaluation-checkpoint.ipynb new file mode 100644 index 00000000..73690b63 --- /dev/null +++ b/notebooks/.ipynb_checkpoints/Deep_dive_into_RAG_evaluation-checkpoint.ipynb @@ -0,0 +1,1018 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Deep dive into RAG Evaluation\n", + "\n", + "In this notebook, we'll show you how to evaluate the output of a RAG system. The high-level RAG flow is depicted in the diagram below.\n", + "![Screenshot 2024-03-11 at 10.05.47.png](data:image/png;base64,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JCABCUhAAgrQtgEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhLoCgEF6K5gNVIJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhJQgLYNSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQQFcIKEB3BauRSkACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAK0bUACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAS6QkABuitYjVQCEpCABCQggX4h8Mwzz6R58+alp556Ki266KJp6tSpaZFFFhmXxXv66afTY489ligT5Vh88cXHZTnMtAQkIAEJSEACEpCABCQwfggoQI+fujKn45wATv+tt96a5s6dmyZNmpSmTZuWVl999bTYYouN85KZfQlIQAK9TeC5554L0fWOO+5It99+e3rwwQcTf1tqqaXSKqusklZbbbW09NJLR99cL0mr1Ur33ntvOu+889KcOXPSi1/84rTpppvGffTl4yk8++yzCQYnn3xyuvPOO9Mmm2yStt566zRx4sTxVAzzKgEJSEACC0CAvp8+/4EHHgjbV70VGzd58uS07LLLhk1kYnK82bZqefxdAhKQgAR6l4ACdO/WjTnrIwIIHTfffHM69NBD05///OcY2CE+z5w5M2200UZ9VFKLIgEJSKB3COBYs9r3mmuuSaeddlq67LLL0t13350eeeSRxHes/l1++eXTy1/+8rTNNtukV73qVWnJJZdMEyZMGCgE/fcNN9yQfvzjH6cTTjghbbbZZumAAw5IG2ywQayGHrhwjH5BWHjyySdjRfOUKVNCSGgnKLPqefbs2enf//3f01VXXZXe+973ps985jNxzxhlf1Cy1AvlYbU5IgiTtIohgzD5BwlIQALzTeDhhx8OG3bxxRdH/0o/Ww280cOELPbvbW97W3rFK14RthEx2iCBQqCMN/iJXWbMoX0udPwpAQnMDwEF6Pmh5DUSGCEBnOkzzjgj/cu//EusvkPcWGGFFULE+PCHPzzC2L1dAhKQgATqBHCw77vvvnThhRemY445Jv3xj3+Mf7OFBsIz/fDjjz+ennjiiXC83/jGN6Zdd901Vjcvt9xyA6uCEaCvvfba9J3vfCcdffTRaauttkof+9jHQqwmrrEMlBFB/ZJLLkn33HNPCOkIB+221eBNnD/96U/ps5/9bPrLX/4Sk6CI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nN/rodQ348u6HeBa6vm1r31tPJf1e6vMqfd6oL7pjyh7vT+COX0hzOBer2/iog/E/lHuejulnLRz6rspbTjzfFFnTWnTf9IPYr+o+3qgnWM/m54xrsX2Mq6mj6i3NeroVa96VdivJrtPubG79IdNzGnn2C/KXy83aePD8Iw12QDSZkze5A9wL+0L+4EvVQ/cS1vj+W5iXto5zyftvB6GG6vBivqCXb2d8jyTZ9pqO1+EctM3dTJOHM73pJ3QTrFddebUL2n/5S9/CbtQr2/sFX0abb0euJZy01Yodz3AnGeTtto0VuIZI224Nflg9OHkm089wBhWZZxW/57+AOb0i02+J/0xeeY5IZ56nVFuxojYsnp/TLlpn5dffnnj2JpnstihJuakzfNB2sRTT5u80zfgO8OwHujXTj311MZnm7xS37Tzpj6RtIvf2/SMcQ/3Eke93OSD+r7ssstijMy/aU/YEGw9/SljB8Y7lLsp79yzsISFXoDmQaGRX3DBBdEp01HxwGPcaIgEOuVdd901veUtb4kGVO+gaHC///3v0zHHHNPYOeK877PPPuGE1wc/xE9aH//4xxs7KK7fa6+90rve9a4YMHJ9CeSdTunMM89MRxxxxKAHnXsxZO95z3vSa17zmkEiMJ3bTXnQw72Uvz74YdC1ww47pHe84x2Nzhyd0umnn55+97vfBbOSL36SNp0y+X79618/aOCFMcOYwI206w86BvDtb397fJrEc4z4H/7wh2BOfcGiBOqHwd4HPvCBcAbrzOnMGPT89re/TWecccagTooOhjLvvvvu0VnU65vB0gknnJB+85vfRN2VdMtPjMLnP//5GITUOxjSplP/9a9/nU488cRyy8BPOvU3vvGNad999420B7742y/U96xZs9LRRx8dzmT9ewZNe+65Z9R3fbALIwYepE2bqTs3DJa23XbbKHeTYFPaGvWNcagHOmWeEwasMKgG0maQ+4tf/CJdeumlg5hz7Xvf+9604447NjKnrZ599tnpm9/85qB2yr0YQer7da97Hf98XiBtBrqHH354OvfccweVG05ve9vboq02Ddx4LmD+3e9+d9BEC22DtPfYY4/01re+9Xnp8g/aOf0L7eWss856nvPN97TzLbfcMtobBrneXkraMCee+oCVdj5z5sz0hje8YZBjRVujvg877LB4xuoDbQYdpP3O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1lsvTZ48eaFv6AKQgAQk0KsEEBzmzJmTbrnllvS6170urbzyyh1nFaN+4403pr/+9a/pFa94RVpzzTXTpEmTOo7PGyUgAQlI4IUhwBj+jjvuSJdffnlaffXV00tf+tIRTUg+/fTTadasWenhhx9Ob33rW0PQfmFKYioSkIAEJCABCUhgMAEWSc2ePTuxaPY1r3lNLL4afFX//KXvBeinnnoqnXXWWenKK69Mm266aXr1q189osFr/1S9JZGABCTQmwQef/zxdOmll6aLL744bbXVVumVr3xlx2+uENd5550X8b3zne+MSUgF6N6sd3MlAQlIoEoAAZqJyJNOOiktv/zyaeutt05LLbVUx6ugH3zwwXTIIYfEmzDve9/70pJLLllNzt8lIAEJSEACEpDAC0aAcQ6T4uecc04smGJynMn2fg59L0DPnTs3/eY3v4nXr7fbbru0zjrruPqtn1u0ZZOABMY9AVap8dbKH//4x7T22munLbfcMk2ZMqWjcj3wwAPp9NNPT3fffXfacccd06qrrtqxmN1RBrxJAhKQgAQ6JsCWGQjQiMe77LJLvBHTyTYcOHk33HBDOvjggxP+wDbbbNOxXem4MN4oAQlIQAISkIAEKgR485c3vS666KJYdIXf28+h7wXoe+65J33/+9+PveP23HPPtMoqq3S8cqKfG4Jlk4AEJNArBNgDmlVvZ555ZvTdO+ywQ6xY6yR/d911VzrttNNi4pFZZVbRdSJedJK290hAAhKQwMgI8ErqH/7wh3iTcZ999kmrrbZaR5OI7K14xRVXpI9//OPpK1/5Stp4441dkDKyqvFuCUhAAhKQgARGSIDtItl68pRTTkkzZsxIO+200whj7O3b+16AvvPOO9PXvva1EJ733Xffvt9Tpbebm7mTgAQkMDwBhAL6blYu8zur3jh8qpNw++23h0Ffbrnl0hZbbDGi17c7Sd97JCABCUigcwJPPvlkOvXUU9MFF1yQGMevscYaHQvQbO1EHEceeWRsx+RkZOf14p0SkIAEJCABCYycAL7u9ddfn4477ri00korJbYI6+fQ9wI0h5ccdNBBMWBl0Ln00kv3c31aNglIQALjngCGmC0zWLmM+LDbbrt1vFfnrbfeGgI0b79svvnmIWQrOoz7JmIBJCCBhYQAZ7kgQLM/4gEHHDAiAZpzBfbbb7907LHHxsHk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LLoEJDD+CCBAsx3TueeeG9tncKbLSLbgYB/pI4880i04xl9TMMcSkIAEJCCBviNQBGi2B2MF9N577913ZawWqO9XQN97773piCOOSCuvvHLadttt0+KLL14tv79LQAISkECPEeA04Pvvvz+xX+eTTz6ZttlmmzgVuJNsspf0BRdckJZddtm00UYbdRxPJ2l7jwQkIAEJjIzAM888E7Zg9uzZaYcddojxfKcC9JVXXpm+/e1vpy9+8YtxLsDIcubdEpCABCQgAQlIYGQEEKBvv/32OGx5+vTpabvtthtZhD1+d98L0PPmzUs33nhjmjp1alp99dXTIoss0uNVYvYkIAEJLNwEEKARnhGPMcqrrbZax303NoDtPKZMmRKzytqAhbttWXoJSGB8EcAG3HfffemBBx6Icfy0adPShAkTFrgQ2BXiuOqqq9LGG28cfsECR+INEpCABCQgAQlIYBQJMD557LHH0p133hn+Km969XPoewGaCmXwymC1kxUT/Vz5lk0CEpBArxKg7+ZDGEnfPVrx9Con8yUBCUig3wmUsTy2oBPxufAhnmeffbbjCc0Sjz8lIAEJSEACEpDAaBFYmPzVvhegR6tRGI8EJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQksGAEF6AXj5dUSkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQwnwQUoOcTlJdJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpDAghHoewGa/VQ4QZs94zx8asEah1dLQAISGCsCZa9O0h9J313iwQZMmjRprIpjuhKQgAQk0CEB9m3mPBf68JGcCUAcTz/9dFp00UVHtJd0h8XwNglIQAISkIAEJDCIwMKkWfa9AP3444+na665Ji2++OJpxowZafLkyYMq3D9IQAISkEDvEMAIP/HEE+muu+6KA6PouzsVobEBnCq82GKLpRVXXFEb0DvVbE4kIAEJDEsA0fiOO+5I99xzT1pvvfViPN/JQYTYlfvvvz9dfvnl6Q1veEPEM2ziXiABCUhAAhKQgAS6SIDxyaOPPppuvfXWNGXKlLT22mt3MbWxj7rvBWgGrD/72c/SKquskt71rnelJZZYYuypmwMJSEACEmhLAEN83333pfPPPz899dRTadttt03Tpk1re/1QXyBin3vuuSE+b7TRRooOQ8HyOwlIQAI9RoAV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)" + ], + "metadata": { + "id": "eXdiZhdNJU6N" + } + }, + { + "cell_type": "markdown", + "source": [ + "We will focus on the evaluation of **Retrive** and **Response** (or **Generation**), and present a set of metrics for each phase. We will deep dive into each metric, to give you a full understanding of how we evaluate models and why we do it this way, and provide code so you can repdroduce on your own data.\n", + "\n", + "To demonstrate the metrics, we will use data from the [Docugami's KG-RAG](https://github.com/docugami/KG-RAG-datasets/tree/main/sec-10-q/data/v1) dataset, a RAG dataset for financial 10Q filing reports. We will focus only on evaluation, without performing the actual Retrieval and response Generation steps." + ], + "metadata": { + "id": "Vi4P1tqgxJxH" + } + }, + { + "cell_type": "markdown", + "source": [ + "# Table of content\n", + "\n", + "1. [Getting started](#getting-started)\n", + "2. [Retrieval Evaluation](#retrieval-evaluation)\n", + "3. [Generation Evaluation](#generation-evaluation)\n", + "4. [Final Comments](#final-comments)" + ], + "metadata": { + "id": "5bnEyZUl_KmS" + } + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "## Getting Started\n", + "\n", + "Let's start by setting the environment and downloading the dataset." + ], + "metadata": { + "id": "rVLK7Bhux8Bs" + } + }, + { + "cell_type": "code", + "source": [ + "%%capture\n", + "!pip install llama-index cohere openai\n", + "!pip install mistralai" + ], + "metadata": { + "id": "VmGk_rOco3m5" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# required imports\n", + "import cohere\n", + "from getpass import getpass\n", + "import os\n", + "import re\n", + "import json\n", + "import numpy as np\n", + "import pandas as pd\n", + "from llama_index.core import SimpleDirectoryReader\n", + "from llama_index.core.llama_dataset import download_llama_dataset, LabelledRagDataset\n", + "from openai import Client\n", + "from mistralai.client import MistralClient" + ], + "metadata": { + "id": "SIpPuVxfo_vz" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "For Response evaluation, we will use an LLM as a judge.\n", + "Any LLM can be used for this goal, but because evaluation is a very challenging task, we recommend using powerful LLMs, possibly as an ensemble of models. In [previous work](https://arxiv.org/pdf/2303.16634.pdf), it has been shown that models tend to assign higher scores to their own output. Since we generated the answers in this notebook using `command-r`, we will not use it for evaluation. We will provide two alternatives, `gpt-4` and `mistral`. We set `gpt-4` as the default model because, as mentioned above, evaluation is challenging, and `gpt-4` is powerful enough to efficiently perform the task." + ], + "metadata": { + "id": "J0ZO3ki_yIJE" + } + }, + { + "cell_type": "code", + "source": [ + "# Get keys\n", + "openai_api_key = getpass(\"Enter your OpenAI API Key: \")\n", + "# uncomment if you want to use mistral\n", + "#mistral_api_key = getpass[\"Enter your Mistral API Key: \"]\n", + "\n", + "# Define the model you want to use - you can replace gpt-4 with any other gpt version\n", + "model = \"gpt-4\"\n", + "# uncomment if you want to use mistral\n", + "#model = \"mistral-large-latest\"\n" + ], + "metadata": { + "id": "-SdZGWLTtLok", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "46d48939-5547-4e53-de78-9ae16440107d" + }, + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter your OpenAI API Key: ··········\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "if model == \"gpt-4\":\n", + " client = Client(api_key=openai_api_key)\n", + "else:\n", + " client = MistralClient(api_key=mistral_api_key)" + ], + "metadata": { + "id": "Zk02dD_9mc7B" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# let's define a function to get the model's response for a given input\n", + "def get_response(model, client, prompt):\n", + " response = client.chat.completions.create(\n", + " model=model,\n", + " messages=[{\"role\": \"user\", \"content\": prompt}],\n", + " temperature=0)\n", + " return response.choices[0].message.content" + ], + "metadata": { + "id": "Kx4cxDGw6LI_" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# load the DocugamiKgRagSec10Q dataset\n", + "if os.path.exists(\"./data/source_files\") and os.path.exists(\"./data/rag_dataset.json\"):\n", + " rag_dataset = LabelledRagDataset.from_json(\"./data/rag_dataset.json\")\n", + " documents = SimpleDirectoryReader(input_dir=\"./data/source_files\").load_data(show_progress=True)\n", + "else:\n", + " rag_dataset, documents = download_llama_dataset(\"DocugamiKgRagSec10Q\", \"./data\")" + ], + "metadata": { + "id": "voJk7dPvuSdN", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "1dd2c527-7d4a-4278-e14b-2c9479ad5caf" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Loading files: 100%|██████████| 20/20 [01:44<00:00, 5.21s/file]\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "## Retrieval Evaluation\n", + "\n", + "In the Retrieval phase, we evaluate the set of **retrieved documents** against the **golden documents** set.\n", + "\n", + "We use three standard metrics to evaluate retrieval:\n", + "\n", + "* **Precision**: the proportion of returned documents that are relevant, according to the gold annotation\n", + "* **Recall**: the proportion of relevant documents in the gold data found in the retrieved documents\n", + "* **Mean Average Precision** (**MAP**): measures the capability of the retriever to return relevant documents at the top of the list\n", + "\n", + "We implement these three metrics in the class below:" + ], + "metadata": { + "id": "lB6vO4JvMEkT" + } + }, + { + "cell_type": "code", + "source": [ + "class RetrievalEvaluator:\n", + "\n", + " def compute_precision(self, retrieved_documents, golden_documents):\n", + " # compute the percentage of retrieved documents found in the golden docs\n", + " return len(set(retrieved_documents).intersection(golden_documents)) / len(retrieved_documents)\n", + "\n", + " def compute_recall(self, retrieved_documents, golden_documents):\n", + " # compute the percentage of golden documents found in the retrieved docs\n", + " return len(set(retrieved_documents).intersection(golden_documents)) / len(golden_documents)\n", + "\n", + " def compute_mean_average_precision(self, retrieved_documents, golden_documents):\n", + " # check which among the retrieved docs is found in the gold, keeping the order\n", + " correct_retrieved_documents = [1 if x in golden_documents else 0 for x in retrieved_documents]\n", + " # compute map\n", + " map = np.mean([sum(correct_retrieved_documents[: i + 1]) / (i + 1) for i, v in enumerate(correct_retrieved_documents) if v == 1])\n", + " return map\n", + "\n", + " def run_evals(self, retrieved_documents, golden_documents):\n", + " precision = round(self.compute_precision(retrieved_documents, golden_documents),2)\n", + " recall = round(self.compute_recall(retrieved_documents, golden_documents),2)\n", + " map = round(self.compute_mean_average_precision(retrieved_documents, golden_documents),2)\n", + " results = {'precision': [precision],\n", + " 'recall': [recall],\n", + " 'map': [map]}\n", + " results = pd.DataFrame(results)\n", + " return results\n", + "\n" + ], + "metadata": { + "id": "CooNq035eU6f" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Let's now see how to use the class above to compute the results on a single datapoint." + ], + "metadata": { + "id": "MWW2VM-Tj8iQ" + } + }, + { + "cell_type": "code", + "source": [ + "# select the index of a single datapoint - the first one in the dataset\n", + "idx = 0\n", + "\n", + "# select the query\n", + "query = rag_dataset[idx].query\n", + "\n", + "# and the golden docs\n", + "golden_docs = rag_dataset[idx].reference_answer.split('SOURCE(S): ')[1].split(', ')\n", + "\n", + "# let's assume we have the following set of retrieved docs\n", + "retrieved_docs = ['2022 Q3 AAPL.pdf', '2023 Q1 MSFT.pdf', '2023 Q1 AAPL.pdf']\n", + "\n", + "print(f'Query: {query}')\n", + "print(f'Golden docs: {golden_docs}')\n", + "print(f'Retrieved docs: {retrieved_docs}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QyMGDqaqe7fg", + "outputId": "e95242c7-dcdd-48bb-9da2-52e25a2a2d41" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Query: How has Apple's total net sales changed over time?\n", + "Golden docs: ['2022 Q3 AAPL.pdf', '2023 Q1 AAPL.pdf', '2023 Q2 AAPL.pdf', '2023 Q3 AAPL.pdf']\n", + "Retrieved docs: ['2022 Q3 AAPL.pdf', '2023 Q1 MSFT.pdf', '2023 Q1 AAPL.pdf']\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# we can now instantiate the evaluator\n", + "evaluate_retrieval = RetrievalEvaluator()\n", + "\n", + "# and run the evaluation\n", + "evaluate_retrieval.run_evals(retrieved_docs,golden_docs)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 81 + }, + "id": "Ron8lm3Z1t1M", + "outputId": "a37eee30-c318-4a2f-8dec-bfd8f4d8c8f2" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " precision recall map\n", + "0 0.67 0.5 0.83" + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
precisionrecallmap
00.670.50.83
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "dataframe", + "summary": "{\n \"name\": \"evaluate_retrieval\",\n \"rows\": 1,\n \"fields\": [\n {\n \"column\": \"precision\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.67,\n \"max\": 0.67,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.67\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"recall\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.5,\n \"max\": 0.5,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.5\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"map\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.83,\n \"max\": 0.83,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.83\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" + } + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "What are the figures above telling us?\n", + "\n", + "* Precision (0.67) tells us that 2 out of 3 of the retrieved docs are correct\n", + "* Recall (0.5) means that 2 out of 4 relevant docs have been retrieved\n", + "* MAP (0.83) is computed as the average of 1/1 (the highest ranked doc is correct) and 2/3 (the 2nd ranked doc is wrong, the 3rd is correct).\n", + "\n", + "While the example here focuses on a single datapoint, you can easily apply the same metrics to all your dataset and get the overall performance of your Retrieve phase." + ], + "metadata": { + "id": "sL-sIiSl2vw9" + } + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "## Generation Evaluation\n", + "\n", + "Evaluating grounded generation (the second step of RAG) is notoriously difficult, because generations are usually complex and rich of information, and simply labelling an answer as \"good\" or \"bad\" is not enough.\n", + "To overcome this issue, we first decompose complex answers into a set of basic *claims*, where a claim is any sentence or part of a sentence in the answer that expresses a verifiable fact. Subsequently, we check the validity of each claim independently, defining the overall quality of the answer based on the correctness of the claims it includes.\n", + "\n", + "We use claims to compute three metrics:\n", + "\n", + "* **Faithfulness**, which measures how many of the claims in the generated response are supported by the retrieved documents. This is a fundamental metric, as it tells us how *grounded* in the documents the response is, and, contextually, it allows us to spot hallucinations\n", + "\n", + "* **Correctness**, which checks which claims in the response also occur in the gold answer\n", + "\n", + "* And **Coverage**, by which we assess how many of the claims in the gold answer are included in the generated response.\n", + "\n", + "Note that Faithfulness and Correctness share the exact same approach, the difference being that the former checks the claims against the supporting docs, while the latter against the golden answer.\n", + "Also, while Correctness is measuring the precision of the claims in the response, Coverage can be seen as complementary, as it measures recall." + ], + "metadata": { + "id": "mwEyE9IaklPL" + } + }, + { + "cell_type": "markdown", + "source": [ + "### Claim Extraction\n", + "\n", + "Let's now see how we implement the evaluation described above using LLMs. Let's start with **claim extraction**." + ], + "metadata": { + "id": "ySgduJrTTjvK" + } + }, + { + "cell_type": "code", + "source": [ + "# first, let's define a function which extracts the claims from a response\n", + "def extract_claims(query, response, model, client):\n", + "\n", + " # define the instructions on how to extract the claims\n", + " preamble = \"You are shown a prompt and a completion. You have to identify the main claims stated in the completion. A claim is any sentence or part of a sentence that expresses a verifiable fact. Please return a bullet list, in which every line includes one of the claims you identified. Do not add any further explanation to the bullet points.\"\n", + "\n", + " # build the prompt\n", + " prompt = f\"{preamble}\\n\\nPROMPT: {query}\\n\\nCOMPLETION: {response}\"\n", + "\n", + " # get the claims\n", + " claims = get_response(model, client, prompt)\n", + "\n", + " return claims\n" + ], + "metadata": { + "id": "X2fQa0Vbuy3W" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# now, let's consider this answer, which we previously generated with command-r\n", + "response = \"Apple's total net sales experienced a decline over the last year. The three-month period ended July 1, 2023, saw a total net sale of $81,797 million, which was a 1% decrease from the same period in 2022. The nine-month period ended July 1, 2023, fared slightly better, with a 3% decrease in net sales compared to the first nine months of 2022.\\nThis downward trend continued into the three and six-month periods ending April 1, 2023. Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022.\"\n", + "\n", + "# let's extract the claims\n", + "claims = extract_claims(query, response, model, client)\n", + "\n", + "# and see what the model returns\n", + "print(f\"List of claims extracted from the model's response:\\n\\n{claims}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "y_0NXZEfu0AJ", + "outputId": "3fa32ab2-6898-449f-f062-187df7aea41e" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "List of claims extracted from the model's response:\n", + "\n", + "- Apple's total net sales experienced a decline over the last year.\n", + "- The three-month period ended July 1, 2023, saw a total net sale of $81,797 million.\n", + "- This was a 1% decrease from the same period in 2022.\n", + "- The nine-month period ended July 1, 2023, had a 3% decrease in net sales compared to the first nine months of 2022.\n", + "- The downward trend continued into the three and six-month periods ending April 1, 2023.\n", + "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022.\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Claim Assessment\n", + "\n", + "Nice! now that we have the list of claims, we can go ahead and **assess the validity** of each claim." + ], + "metadata": { + "id": "50QRlCVe7dZf" + } + }, + { + "cell_type": "code", + "source": [ + "# Let's create a function that checks each claim against a reference text,\n", + "# which here we will call \"context\". As you will see, we will use different contexts,\n", + "# depending on the metric we want to compute.\n", + "\n", + "def assess_claims(query, claims, context, model, client):\n", + "\n", + " # define the instructions on how to perform the assessment.\n", + " # the model has to append to each row a binary SUPPORTED tag\n", + " preamble = \"You are shown a prompt, a context and a list of claims. You have to check which of the claims in the list are supported by the context. Please return the list of claims exactly as is it, just append to each row “SUPPORTED=1” if the claim is supported by the context, or “SUPPORTED=0” if the claim is not supported by the context. Do not add any further explanation to the bullet points.\"\n", + "\n", + " # turn list into string\n", + " context = '\\n'.join(context)\n", + "\n", + " # build the prompt\n", + " prompt = f\"{preamble}\\n\\nPROMPT: {query}\\n\\nCONTEXT:\\n{context}\\n\\nCLAIMS:\\n{claims}\"\n", + "\n", + " # get the response\n", + " assessment = get_response(model, client, prompt)\n", + "\n", + " return assessment" + ], + "metadata": { + "id": "jrg9-dlMTRpB" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Faithfulness" + ], + "metadata": { + "id": "1OmD9pKxArk7" + } + }, + { + "cell_type": "code", + "source": [ + "# Let's start with Faithfulness: in this case, we want to assess the claims\n", + "# in the response against the retrieved documents (i.e., context = retrieved documents)\n", + "\n", + "# for the sake of clarity, we report the actual text of the retrieved documents\n", + "retrieved_documents = ['Products and Services Performance\\nThe following table shows net sales by category for the three- and six-month periods ended April 1, 2023 and March 26, 2022 (dollars in millions):\\nThree Months Ended Six Months Ended\\nApril 1,\\n2023March 26,\\n2022 ChangeApril 1,\\n2023March 26,\\n2022 Change\\nNet sales by category:\\niPhone $ 51,334 $ 50,570 2 %$ 117,109 $ 122,198 (4)%\\nMac 7,168 10,435 (31)% 14,903 21,287 (30)%\\niPad 6,670 7,646 (13)% 16,066 14,894 8 %\\nWearables, Home and Accessories 8,757 8,806 (1)% 22,239 23,507 (5)%\\nServices 20,907 19,821 5 % 41,673 39,337 6 %\\nTotal net sales $ 94,836 $ 97,278 (3)%$ 211,990 $ 221,223 (4)%\\niPhone\\niPhone net sales were relatively flat during the second quarter of 2023 compared to the secon d quarter of 2022. Year-over-year iPhone net sales decreased\\nduring the first six months of 2023 due primarily to lower net sales from the Company’ s new iPhone models launched in the fourth quarter of 2022.\\nMac\\nMac net sales decreased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to lower net sales of\\nMacBook Pro.\\niPad\\niPad net sales decreased during the second quarter of 2023 compared to the second quarter of 2022 due primarily to lower net sales of iPad Pro and iPad Air.\\nYear-over-year iPad net sales increased during the first six months of 2023 due primarily to higher net sales of iPad, partially offset by lower net sales of iPad\\nmini .\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales were relatively flat during the second quarter of 2023 compared to the second quarter of 2022. Year-over-year\\nWearables, Home and Accessories net sales decreased during the first six months of 2023 due primarily to lower net sales of AirPods .\\nServices\\nServices net sales increased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to higher net sales from\\ncloud services, music and advertising.® ®\\n®\\n®\\nApple Inc. | Q2 2023 Form 10-Q | 16', 'Products and Services Performance\\nThe following table shows net sales by category for the three- and nine-month periods ended July 1, 2023 and June 25, 2022 (dollars in millions):\\nThree Months Ended Nine Months Ended\\nJuly 1,\\n2023June 25,\\n2022 ChangeJuly 1,\\n2023June 25,\\n2022 Change\\nNet sales by category:\\niPhone $ 39,669 $ 40,665 (2)%$ 156,778 $ 162,863 (4)%\\nMac 6,840 7,382 (7)% 21,743 28,669 (24)%\\niPad 5,791 7,224 (20)% 21,857 22,118 (1)%\\nWearables, Home and Accessories 8,284 8,084 2 % 30,523 31,591 (3)%\\nServices 21,213 19,604 8 % 62,886 58,941 7 %\\nTotal net sales $ 81,797 $ 82,959 (1)%$ 293,787 $ 304,182 (3)%\\niPhone\\niPhone net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales from\\ncertain iPhone models, partially of fset by higher net sales of iPhone 14 Pro models.\\nMac\\nMac net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales of laptops.\\niPad\\niPad net sales decreased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to lower net sales across most iPad models. Year-\\nover-year iPad net sales were relatively flat during the first nine months of 2023.\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales increased during the third quarter of 2023 compare d to the third quarter of 2022 due primarily to higher net sales of\\nWearables, which includes AirPods , Apple Watch and Beats products, partially offset by lower net sales of accessories. Year-over-year Wearables, Home\\nand Accessories net sales decreased during the first nine months of 2023 due primarily to lower net sales of W earables and accessories.\\nServices\\nServices net sales increased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to higher net sales from advertising, cloud\\nservices and the App Store . Year-over-year Services net sales increased during the first nine months of 2023 due primarily to higher net sales from cloud\\nservices, advertising and music.® ® ®\\n®\\nApple Inc. | Q3 2023 Form 10-Q | 16']\n", + "\n", + "# get the Faithfulness assessment for each claim\n", + "assessed_claims_faithfulness = assess_claims(query=query,\n", + " claims=claims,\n", + " context=retrieved_documents,\n", + " model=model,\n", + " client=client)\n", + "\n", + "print(f\"Assessment of the claims extracted from the model's response:\\n\\n{assessed_claims_faithfulness}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5VmLE4yCwEMe", + "outputId": "10874986-1f91-45a3-c081-dc2aae3fd618" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Assessment of the claims extracted from the model's response:\n", + "\n", + "- Apple's total net sales experienced a decline over the last year. SUPPORTED=1\n", + "- The three-month period ended July 1, 2023, saw a total net sale of $81,797 million. SUPPORTED=1\n", + "- This was a 1% decrease from the same period in 2022. SUPPORTED=1\n", + "- The nine-month period ended July 1, 2023, had a 3% decrease in net sales compared to the first nine months of 2022. SUPPORTED=1\n", + "- The downward trend continued into the three and six-month periods ending April 1, 2023. SUPPORTED=1\n", + "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022. SUPPORTED=1\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "Great, we now have an assessment for each of the claims: in the last step, we just need to use these assessments to define the final score." + ], + "metadata": { + "id": "vBbLuSkO-iN7" + } + }, + { + "cell_type": "code", + "source": [ + "# given the list of claims and their label, compute the final score\n", + "# as the proportion of correct claims over the full list of claims\n", + "def get_final_score(claims_list):\n", + " supported = len(re.findall(\"SUPPORTED=1\", claims_list))\n", + " non_supported = len(re.findall(\"SUPPORTED=0\", claims_list))\n", + " score = supported / (supported+non_supported)\n", + " return round(score, 2)" + ], + "metadata": { + "id": "tFk-IxK_wDVT" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "score_faithfulness = get_final_score(assessed_claims_faithfulness)\n", + "print(f'Faithfulness: {score_faithfulness}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Z680DvFOW2Ea", + "outputId": "1666057d-7981-43d3-f4bb-c10fdc861cae" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Faithfulness: 1.0\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "The final Faithfulness score is 1, which means that the model's response is fully grounded in the retrieved documents: that's a very good news :)\n", + "\n", + "Before moving on, let's modify the model's response by adding a piece of information which is **not** grounded in any document, and re-compute Faithfulness." + ], + "metadata": { + "id": "3_Ks8ELQrdQO" + } + }, + { + "cell_type": "code", + "source": [ + "# let's mess up the century, changing 2022 to 1922\n", + "modified_response = response.replace('2022', '1922')\n", + "\n", + "# extract the claims from the modified response\n", + "modified_claims = extract_claims(query, modified_response, model, client)\n", + "\n", + "# and get assess the modified claims\n", + "assessed_modified_claims = assess_claims(query=query,\n", + " claims=modified_claims,\n", + " context=retrieved_documents,\n", + " model=model,\n", + " client=client)\n", + "\n", + "print(f\"Assessment of the modified claims:\\n\\n{assessed_modified_claims}\\n\")\n", + "\n", + "score_faithfulness_modified_claims = get_final_score(assessed_modified_claims)\n", + "print(f'Faithfulness: {score_faithfulness_modified_claims}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "YEZUA8XMAxLE", + "outputId": "9b6e59b1-a4f9-46bf-cdf8-a4f520462d12" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Assessment of the modified claims:\n", + "\n", + "- Apple's total net sales experienced a decline over the last year. SUPPORTED=1\n", + "- The three-month period ended July 1, 2023, saw a total net sale of $81,797 million. SUPPORTED=1\n", + "- This was a 1% decrease from the same period in 1922. SUPPORTED=0\n", + "- The nine-month period ended July 1, 2023, had a 3% decrease in net sales compared to the first nine months of 1922. SUPPORTED=0\n", + "- The downward trend continued into the three and six-month periods ending April 1, 2023. SUPPORTED=1\n", + "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 1922. SUPPORTED=0\n", + "\n", + "Faithfulness: 0.5\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "As you can see, by assessing claims one by one, we are able to spot **hallucinations**, that is, the (corrupted) cases in which the information provided by the model is not grounded in any of the retrieved documents." + ], + "metadata": { + "id": "TccmzE9TCQsN" + } + }, + { + "cell_type": "markdown", + "source": [ + "### Correctness\n", + "\n", + "As said, Faithfulness and Correctness share the same logic, the only difference being that we will check the claims against the gold answer. We can therefore repeat the process above, and just substitute the `context`." + ], + "metadata": { + "id": "bPK-MND1riQD" + } + }, + { + "cell_type": "code", + "source": [ + "# let's get the gold answer from the dataset\n", + "golden_answer = rag_dataset[idx].reference_answer\n", + "\n", + "# and check the claims in the response against the gold.\n", + "# note that assess_claims takes exactly the same args as with Faithfulness\n", + "# except for the context, that now is the golden_answer\n", + "assessed_claims_correctness = assess_claims(query=query,\n", + " claims=claims,\n", + " context=golden_answer, # note the different context\n", + " model=model,\n", + " client=client)\n", + "\n", + "\n", + "print(f\"Assess the claims extracted from the model's response against the golden answer:\\n\\n{assessed_claims_correctness}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "qVeQDVDYEr45", + "outputId": "a14a5b09-b8f7-4563-ade5-fe2cd1384cfb" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Assess the claims extracted from the model's response against the golden answer:\n", + "\n", + "- Apple's total net sales experienced a decline over the last year. SUPPORTED=1\n", + "- The three-month period ended July 1, 2023, saw a total net sale of $81,797 million. SUPPORTED=1\n", + "- This was a 1% decrease from the same period in 2022. SUPPORTED=0\n", + "- The nine-month period ended July 1, 2023, had a 3% decrease in net sales compared to the first nine months of 2022. SUPPORTED=0\n", + "- The downward trend continued into the three and six-month periods ending April 1, 2023. SUPPORTED=1\n", + "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022. SUPPORTED=0\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "As mentioned above, automatic evaluation is a hard task, and even when using powerful models, claim assessment can present problems: for example, the third claim is labelled as 0, even if it might be inferred from the information in the gold answer." + ], + "metadata": { + "id": "V4pCRJ0qPQWT" + } + }, + { + "cell_type": "code", + "source": [ + "# we can now compute the final Correctness score\n", + "score_correctness = get_final_score(assessed_claims_correctness)\n", + "print(f'Correctness: {score_correctness}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "nObA30PzxQha", + "outputId": "2e354428-ea91-4c7e-94b6-31433018058c" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Correctness: 0.5\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "For Correctness, we found that only half of the claims in the generated response are found in the gold answer. Note that this is not necessarily an issue: reference answers are often non-exhaustive, especially in dataset including open-ended questions, like the one we are considering in this post, and *both* the generated and golden answer can include relevant information.\n" + ], + "metadata": { + "id": "4Nd0bQ3rR1c3" + } + }, + { + "cell_type": "markdown", + "source": [ + "### Coverage\n", + "\n", + "We finally move to Coverage. Remember that, in this case, we want to check how many of the claims *in the gold answer* are included in the generated response. To do it, we first need to extract the claims from the gold answer." + ], + "metadata": { + "id": "YhsEJDNXR8OY" + } + }, + { + "cell_type": "code", + "source": [ + "# let's extract the golden claims\n", + "gold_claims = extract_claims(query, golden_answer, model, client)\n", + "\n", + "print(f\"List of claims extracted from the gold answer:\\n\\n{gold_claims}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wJeHJhiAxQjy", + "outputId": "8da8edf0-5605-4548-aab4-002d0202ee88" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "List of claims extracted from the gold answer:\n", + "\n", + "- For the quarterly period ended June 25, 2022, the total net sales were $82,959 million.\n", + "- For the quarterly period ended December 31, 2022, the total net sales were $117,154 million.\n", + "- For the quarterly period ended April 1, 2023, the total net sales were $94,836 million.\n", + "- For the quarterly period ended July 1, 2023, the total net sales were $81,797 million.\n", + "- There was an increase in total net sales from the quarter ended June 25, 2022, to the quarter ended December 31, 2022.\n", + "- There was a decrease in total net sales in the quarters ended April 1, 2023, and July 1, 2023.\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "Then, we check which of these claims is present in the response generated by the model." + ], + "metadata": { + "id": "6VXxxrL1SuFv" + } + }, + { + "cell_type": "code", + "source": [ + "# note that in, this case, the context is the model's response\n", + "assessed_claims_coverage = assess_claims(query=query,\n", + " claims=gold_claims,\n", + " context=response,\n", + " model=model,\n", + " client=client)\n", + "\n", + "\n", + "print(f\"Assess which of the gold claims is in the model's response:\\n\\n{assessed_claims_coverage}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Ro-sYsp5SnOo", + "outputId": "d334a72e-a87a-4900-b9e6-9a6c2140dffb" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Assess which of the gold claims is in the model's response:\n", + "\n", + "- For the quarterly period ended June 25, 2022, the total net sales were $82,959 million. SUPPORTED=0\n", + "- For the quarterly period ended December 31, 2022, the total net sales were $117,154 million. SUPPORTED=0\n", + "- For the quarterly period ended April 1, 2023, the total net sales were $94,836 million. SUPPORTED=0\n", + "- For the quarterly period ended July 1, 2023, the total net sales were $81,797 million. SUPPORTED=1\n", + "- There was an increase in total net sales from the quarter ended June 25, 2022, to the quarter ended December 31, 2022. SUPPORTED=0\n", + "- There was a decrease in total net sales in the quarters ended April 1, 2023, and July 1, 2023. SUPPORTED=1\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# we compute the final Coverage score\n", + "score_coverage = get_final_score(assessed_claims_coverage)\n", + "print(f'Coverage: {score_coverage}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "FUvVUN8qSnG2", + "outputId": "e854432a-f13b-4596-fb7c-f9b51ee870ec" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Coverage: 0.33\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "The Coverage score is telling us that 1/3 of the information in the gold answer is present in the generated answer. This is a useful information, that, similarly to what said above regarding Correctness, can raise further questions, such as: is it acceptable to have diverging information in the generated answer? Is any crucial piece of information missing in the generated answer?\n", + "\n", + "The answer to these questions is use case-specific, and has to be made by the end user: The claim-based approach implemented here supports the user by providing a clear and detailed view on what the model is assessing and how." + ], + "metadata": { + "id": "pduSBr2-U_R7" + } + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "## Final Comments\n", + "\n", + "RAG evaluation is a hard task, especially the evaluation of the generated response. In this notebook we offer a clear, robust and replicable approach to evaluation, on which you can build on to build your evaluation pipeline." + ], + "metadata": { + "id": "0-1FsN2dHzMS" + } + } + ] +} diff --git a/notebooks/.ipynb_checkpoints/Document_Parsing_For_Enterprises-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/Document_Parsing_For_Enterprises-checkpoint.ipynb new file mode 100644 index 00000000..9a80a714 --- /dev/null +++ b/notebooks/.ipynb_checkpoints/Document_Parsing_For_Enterprises-checkpoint.ipynb @@ -0,0 +1,1830 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "ssw34RVKHmsJ" + }, + "source": [ + "# Advanced Document Parsing For Enterprises" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b2oYelmWW35Q" + }, + "source": [ + "## Introduction\n", + "\n", + "The bread and butter of natural language processing technology is text. Once we can reduce a set of data into text, we can do all kinds of things with it: question answering, summarization, classification, sentiment analysis, searching and indexing, and more.\n", + "
\n", + "
\n", + "In the context of enterprise Retrieval Augmented Generation (RAG), the information is often locked in complex file types such as PDFs. These formats are made for sharing information between humans, but not so much with language models.\n", + "
\n", + "
\n", + "In this notebook, we will use a real-world pharmaceutical drug label to test out various performant approaches to parsing PDFs. This will allow us to use [Cohere's Command-R model](https://txt.cohere.com/command-r/) in a RAG setting to answer questions and asks about this label, such as \"I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of\" a given pharmaceutical.\n", + "
\n", + "
\n", + "![image.png](data:image/png;base64,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BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABAurZBxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQTGpAAB9WNys7PSCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAkkC6i+++GK33377DdLcdttt3aGHHjqoPz0GC0yYMME98MADgwZcccUVbuWVVx7Unx4IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACzQSSBNSfe+657uCDDx60JFtssYU7+uijB/Wnx2CB9dZbzz3yyCODBlx22WVu1VVXHdSfHggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAALNBJIH1O+www5unXXWyZZq3LhxbrnllmtZwjvuuMOdfvrpWb811ljD7bzzzi3DQ8e9997rTjjhhKxz/Pjxbvfddw+D+vLz17/+tZsxY0a2bhdccIG78cYbs+8E1Pfl5malEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKAHBJIH1J900klu4sSJpav2k5/8xO25557Z8AkTJrhTTz21cNzrr7/eKThf6cMf/rA7//zzC8frx56HHXaYO+OMM7JVI6C+H7cw64QAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvSBAQH0vbIVoGQioj0DoRAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEhkCAgPohQG06SQLqmwryewQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoLMAAfWdjYZ9DALqh52cGSKAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAGBQY9QH1zz//vDv33HPdLbfc4h599FH37LPPujnnnNMtueSSbuWVV3YbbLCB+9CHPuRmn3320s07c+ZMd9FFF7n77rvP3Xvvve7xxx93K6ywQvb7SZMmufe///2lvw0DLrzwQvfAAw9knfvtt182v0suucRNnjw577/iiiu6T3ziE27rrbd2b33rW8NPB30SUD+IhB4IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBygVEdUH/PPfe4zTbbrCPKtddemwXIF404bdo0t8suu7hHHnmkaHDWb88993S77rpr26D8HXfc0V133XXZ+Aru/+Y3v+l+8YtfFE7z0EMPddtuu23hMPUkoL6UhgEIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEAygVEbUP/qq69mLcerRXqlxRZbLGv9ff7553fPPPOM+9Of/uSuv/76bNg111zj3vOe92Tf7T8F02+yySZ5L/32Yx/7mFtggQXcgw8+6H72s5/lww444AC3ww475N3xFxtQ/8lPftJdeuml2Sia5vjx491LL73k7r//fvfiiy86AupjPboRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIHhFxi1AfW33Xab22abbTKx1VZbzV1yySXujW98Y4uggu1/+MMfus0339wtvPDCLcPUsdVWW7k777wz6z9p0iT37W9/280555z5eFOmTHFbbrll3j116lS30EIL5d32iw2oV39N59RTT3XrrrtuPtrLL7/szjvvPLf44ou3BPLnI7z+hRbqYxG6EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACB9AKjNqBeAfT77rtvJrLrrru6ffbZp5LODTfc4L74xS9mv1lxxRXd5MmTBwXka+DZZ5/tDjnkkGy8Pffc0331q1/Nvsf/4oD66667zi2//PLxaF11E1DfFRMjIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACjQRGbUC9AtYVxK40btw4d+utt7o3vOENXWN885vfdOecc042/nHHHZe1Yl/043/+859u/Pjx2aANN9zQnXXWWUWjZcuiZVJSa/fHH3984Xjd9CSgvhslxkEAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBJoJjNqA+qeeesqtvfba+drPP//8bptttnGrr766W2mlldy8886bDyv6su2227qbb765aFBpP83jN7/5TeFw20L9SSed5CZOnFg4Xjc9CajvRolxEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBZgKjNqBeq/3973/fHX744YUCyyyzjNt0003dF77wBTfnnHMOGud973ufe/bZZwf179TjscceKxzFBtRfdtllbtVVVy0cr5ueBNR3o8Q4CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAM4FhD6i/8sor3Ze//OVsqSdMmOBOPfXUwjW4/vrr3Q477JANW3/99d0555xTON5tt92WDbvxxhsLhy+11FLu0ksvdWpd3qZ3v/vd7sUXX8x6HXXUUW7BBRe0gwu/zz777G6dddYpHGYD6m+99Va32GKLFY7XTU8C6rtRYhwEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKCZwLAH1F977bVup512ypb6ox/9aNbKfNEqXHfddU5B6krtAu/Db2fOnOkefPBBN2XKFHf55Ze7adOmhUFu2223dYceemjerS8TJ0509913X9ZPy7TCCiu0DK/aYQPqb7/9drfIIotUnUQ+PgH1OQVfEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBIRMY9oD6X/7yl2677bbLVqhdy/NXXXWV22233bLxPvnJT7pjjjmma4T//ve/7owzznDf+c53st+otXi1Gm/T1772tazlevU777zz3LrrrmsHV/5OQH1lMn6AAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgiMqMCwB9Q//PDD7iMf+Ui20ksttZS76aabCgFOOeUUd+SRR2bDdt99d7fHHnsUjlfWc2BgwC2xxBL54Mceeyz/ri+nnXZaHnC/8cYbu9NPP71leNUOAuqrijE+AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAwsgLDHlD/yiuvuGWWWSZf6+OPP95NmjQp79aXJ5980qlV+qeffjrrr9bmN9poo5Zxpk2blnWvsMIKLf1Dx0MPPZT/Zty4ce7OO+8Mg7LP559/3q211lruxRdfzLrPPvtst8EGG7SMEzpeeukld/XVV7u1117bLbLIIqF3yycB9S0cdCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAj0vMOwB9RI5//zz3YEHHpjj7LDDDm6NNdZwc889t/v973/v1Dr9s88+mw1fZZVV3GWXXeZmnXXWfHx9+d73vueOOOIIN378ePfpT3/aLbvssk6B80899ZS744473MUXX5wH5O+yyy7u61//esvv1fGjH/3I7b333nn/rbfe2k2YMMEtvvjiTkH006dPd1OnTnWXXHJJFnj/wx/+0K255pr5+PYLAfVWg+8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDvC4xIQP1//vMft/nmm7v77ruvo9C1117rilqhDwH1nSag1vB/8pOfuHnmmWfQqK+99po76qijsuD8QQMLehBQX4BCLwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAYJQKjEhAvaxeffVVd8EFF7ijjz46a/099tt0003dfvvtl7U6Hw9T99133+3OOOMMd8sttxT+XuPstttu7otf/KKbb7751Fma7rnnHnfAAQe4Bx54oHCc1VZbzX3iE59wkyZNKgzM14/UCv5Pf/rT7Pd33nln6XIXziDqedhhh2Xrpt5qnX/VVVeNxqATAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoKlA8oB6u0Dbbbed+9a3vmV7Dfqu1uqfeOIJ99hjj7mXXnrJLbbYYm7xxRd3c88996Bxi3ro948++qh75pln3N///nc311xzuXe84x3ZdOaYY46in5T2mzlzpps+fbp75JFH3Jvf/Ga38MILu3e+851u3nnnLf1NqgETJ04sbLGfgPpUwkwHAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBoFRjSgPotttgia4G+dZZ0FQmst956WSB/PIyA+liEbgQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAII1AkoD6p556yj300EODlmjcuHFuhRVWGNSfHoMFpk6d6mbMmDFowOqrr951a/2DfkwPBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgVKBJAH1pVNnAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACPSpAQH2PbhgWCwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQGBoBQioH1pfpo4AAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQowIE1PfohmGxEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBIZWgID6ofVl6ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAI9KkBAfY9uGBYLAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAYGgFCKgfWl+mjgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCjAgTU9+iGYbEQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEhlaAgPqh9WXqCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAj0qQEB9j24YFgsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEBgaAUIqB9a3yRTf/bZZ90pp5ySTWvllVd2EydOTDJdJjI6Ba6//no3bdq0bOE/97nPuXnmmWd0rghLjcAYEbj77ruzY/bJJ590r7zySrbWc8wxh9trr716UuDiiy92f/zjH90ss8ySLeNb3vKWnlxOFgqBMgHKTWUyY7N/L5abJk+e7O6///5sg3z1q1/tqiz3/PPPu3PPPTf7zQorrOA22mijsblBX1/rXtyuY3qDsPI9KzB9+nR31113uccff9y9+OKL+XLusssuboEFFsi7R9OXe+65x1111VXZIm+66aZu/Pjxw7L4vZIPqy5AeaCSzgU6J5BGVoBtMrL+wzX3Y4891s2YMSMrt6n8RioXuOOOO9wNN9yQjbDVVlu55ZZbrnzkUTiEYz79RvvnP//pbr31VvfYY4+55557zg0MDGQzmTBhglt11VXTz7DPp3jWWWdl+dVcc83ltt9++z5f2+FZvdFWtztUKlXLwyq3n3POOYWLs9lmm7n111+/cFg3PZte51Cn0I0y4yCAAAIIIIAAAggggAACCCAwNgUqB9Tffvvt7swzz+xa66CDDnJLLrlk1+Mz4mABBTZusMEG2YAtttjCHX300YNHos+YEdhjjz3cZZddlq3vTTfd5JZaaqkxs+6sKAKjSWDmzJlON9qvu+66QYs955xzut///veD+vdCj2233dbdfPPN2aL85je/cfPPP38vLBbLgEDXApSbuqYaEyP2YrnpK1/5irviiisyf+W3SyyxRMdt8cgjj7j11lsvG2/SpEnu+OOP7/ibfh6hF7drP3uzbqNT4MQTT3THHHNM4cKrfLr88ssXDuv1npdcconbd999s8VU3YjqSIYj9Uo+/KMf/cjtvffe2SofeeSRTsGqpJEVYJuMrP9wzf3d73539mCSro91nUwqF/j+97/vDj/88GyE008/3W288cblI4/CIRzzaTfaz3/+c/flL3+55cG/MIfDDjvMffaznw2dfHYp8L73vc+poYFernvsclVGfLSRqNvt5fuvVcvDV155ZXZ8F23I/fff3+20005Fgzr2S3GdQ51CR2ZGQAABBBBAAAEEEEAAAQQQQGDMClQOqLeVxt2oXX755W6VVVbpZlTGKREgMKwEZoz2Hu2VfSeffLI76qijsq2nlrA/8IEPjNEtyWr3u8BJJ53U8gDUuHHj8uD0+eabz1144YVDSlD3WCOgfkg3CxMfBgHKTcOAPIpm0YvlprEYUP/qq6+6pZdeOttz1lhjDffjH/+40V7Ui9u10Qrx40YCU6dOzYOqtW/svvvujabXDz+eMmWK23LLLfNVUUCVbehAwY6LLrpoPnw0fSGgfuQC6lPn5SO539W9VipaZltPykMORUL90Y+A+u63IwH13VuN9THVMv3aa6/dEkyvN6/MNttsGY0C7TfZZJO+Z0p9fiWgPt0uMxJ1u7Zc0c2aDOf916oB9Q888IDT+oSk3+ttFEp1A+pTXedQpxC2Cp8IIIAAAggggAACCCCAAAIIIBALVA6o/+lPf+oOPPDAfDovv/xyS6Vn3JLtRRddxCuoc616XwgMq+fWr7/ab7/9nALRlW655Ra3+OKLj6pVPeGEE5xela10wQUXuA996EOjavlZWAS6FQg3sDT+cN7cCMtX91gjoD4I8jlaBSg3jdYtNzTL3YvlpjoB9Y8//rj74Ac/mCFtvfXWeaufQ6OWfqqvvPKKW2aZZbIJjx8/3qmluiapF7drk/Xht80E7rjjDvepT30qm8huu+2Wt97dbKqj+9c2QERvDdx+++1H9wqZpR+pgPpeyYcnT56cPzSit5XorSXDlVLn5cO13EXzqXutVDStkdwmRctDv6ERIKC+e9d+D6jnmO9+X+g0pg0c/vjHP57VF7/pTW/q9LO+G576/KrrRpVbFltssTx4ue/QhmmFRqJut5fvvzYtD+stWTvuuGO29eoG1Ke6zqFOYZgOImaDAAIIIIAAAggggAACCCCAwCgUqBxQH6/jn//8Z7fWWmvlvR977LH8O1/SCBAYlsaRqfSGQMob172xRiwFAoMFXnrppfxhshQt8Q6eQ+c+dY81Auo72zJGbwtQburt7cPSOVcnoH60u6UOEhntHix/WgEC6gd7brbZZu6ee+7JBvzhD39wb3zjGwePNEr7jFRA/SjlSrrY/ZSX171WSgrKxEaVAAH13W+ufg+o716CMTsJHH300U4tgCv98Ic/dGuuuWann/Tl8H46v/bTBuqFul159tP91xQB9f18ndNPxw/rggACCCCAAAIIIIAAAggggMBoFiCgfhRsPQLDRsFGYhG7FuDGdddUjDiKBfRwWXj7glrZOuWUU4Z9beoeawTUD/umYoaJBSg3JQZlcskFCKhv3kJ98o3CBEe1AAH1gzdfaE1zzjnndL///e8HjzCK+xBQP3Ibr58C/upeK42cPnMeaQEC6rvfAgTUd2811sfca6+93I9//OOM4YYbbnDLLrvsmCTpp/NrP23AXqjblScB9a17VT9f57SuKV0IIIAAAggggAACCCCAAAIIIDBSAqM2oP68885z06ZNc7PMMovTK8ynT5/urr766uw1lvfdd59bZpllslZNVDE777zztvWdOXOmu+iii5x+d++992avxFxhhRXcyiuvnL0++/3vf3/b32tg02m8/PLL7uyzz3ZTpkxxd911l3vrW9/q1llnHadAzEUWWcRtsMEG2TJsscUWTq23DEWS4S233OJuvvlm98gjj2R/ms9qq63mdONIrSx/4hOfGIpZD5rm888/784999xseR599FH37LPPOgUDLLnkktl2kYeCVWefffZBvz300EPdq6++6saNG+d23nnnQcPV4/TTT3dPPvlk9vtvfOMbbrbZZiscTz1Vqf2DH/zA/fa3v832uQceeCBbFu0jWoatttrKLbzwwqW/14C///3v7uKLL3YPPvigu//++7N9TMunGwUf+9jHMletX1H6+c9/7hQkUpR23XVXN9988xUNyvppe15zzTXZ9+22284tsMAC7rLLLnO/+tWv3C9/+cvMSJWQCuxafvnlS6djB1x//fXutttuyyx+97vfuRdffNGtuOKKbpVVVnGf/vSn3Xve8x47urviiitalv/Xv/61UyuJSmuvvbZbfPHFW8bXttA2nHXWWVv6p+zQ/n3WWWdlx7v2L63D/PPPn+1fWibtXzr+4/TUU0+50047Lev9gQ98wG288cbxKO7f//63+853vuMGBgbcu971Lif3kO6+++78RtH//d//ZfuhPOWn/UiBzLqRpPxILUrq2NNrTJUXhKTXIf/mN79xc801V9ZfLTnJVK/z/dKXvpTle8oj9HpYHTfKvw477DD3zne+M0wi+/zvf/+b7YvaD+68887seNBrW+Wg5dH+vckmm2TbteWHBR3aP7WdlT71qU+58ePHZ/vdhRdemOWr8l1qqaWyZfziF7+YvXL4mWeeccccc0z2G81z7733zr6X/dPxo2NQaZtttnHvfe97y0Zt1F8e1157bWajY13HqY4R7d/almWteyo/Ofnkk/N5/+Mf/3BqdUdJ01h33XWz7+Gftt8BBxwQOpN8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BBBAAAEEEBgrAgTUj5UtzXoigAACPSwwY8YM5185nrVkrMUkCLOHNxaLNuwCBNQPOzkzrCngX4PuJk+enP1ardNPmTLFzT333DWnxs8Q6E8BBc/vs88++copiHHVVVfNu/mCAAIIIIDAcAmo5XGdg9RyttIHP/hBd+GFFw7X7JkPAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINBTAgTU99TmYGEQQACBsSOg1wgfe+yxTq9EvvLKK/MVVxDmbbfd5t72trfl/fiCwFgWIKB+LG/90bPucUDW/vvv73baaafRswIsKQLDJPCVr3zFXXHFFdnc1l13XXfeeecN05yZDQIIIIAAAq0Cf/rTn9z666+f97z88svdKqusknfzBQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAYSwIE1I+lrc26IoAAAj0k8MQTT7h11lmnZYkUTP+DH/zArbTSSi396UBgLAsQUD+Wt/7oWfdXXnkle0jqP//5j5t11lmdWqufY445Rs8KsKQIDJPA+eef7x5//PFsbltssYVbbrnlhmnOzAYBBBBAAIFWgenTp7sLLrjAzTLLLG6hhRbK3hrXOgZdCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggMDYESCgfuxsa9YUAQQQ6CmBZ555xn3uc5/Llmn++ed373//+90mm2zi3vWud/XUcrIwCIy0wF577eWmTZvmZpttNnfZZZe52WeffaQXifkjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAn0jQEB932xKVgQBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgigAB9VW0GBcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgbwQIqO+bTcmKIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCFQRIKC+ihbjIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPSNAAH1fbMpWREEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBA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AAIIIIAAAlUECKivosW4CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAn0jQEB932xKVgQBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgigAB9VW0GBcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgbwQIqO+bTcmKIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCFQRIKC+ihbjIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPSNAAH1fbMpWREEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBKgIE1FfRYlwEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBvhEgoL5vNiUrggACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBFgID6KlqMiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINA3AgTU982mZEUQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEqggQUF9Fi3ERQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEE+kaAgPq+2ZSsCAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEAVAQLqq2gxLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDfCBBQ3zebkhVBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQT+H3t3Hm/V+Pd//IN0R9xmKUKpSJLI3KyvupVCEokKDeJrljQZQskQKmlAZaiMmStEJUMKCRlTGTNkDH2p81vv63df6772PmvvM3SGOr2ux6Oz13Cttdd6rr3X7o/39VkIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURIBAfUG06IsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQZgQI1JeZS8mJIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCBREgEB9QbToiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBmBAjUl5lLyYkggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURIBAfUG06IsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQZgQI1JeZS8mJIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCBREgEB9QbToiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBmBAjUl5lLyYkggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURKBIAvUPPvigXXnllbne98wzz7TBgwfnWs4CBIpb4IYbbrAxY8bkeptBgwbZ2WefnWs5CxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEBg0xMokkD9hAkT7Kqrrsql16FDB7v55ptzLc+2YPXq1W51xYoVs3VjXSkIvP322/bUU0+5d27Xrp3Vq1evFI4if2+p4PzEiRNzdb7iiiusd+/euZazAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ2PYEiD9R3797dGjZs6CQrV65s++67b1bVf/75xx555BFbsGCBLVy40JYuXer6K1Bft25dO/nkk+24444zAvZZGUtk5eTJk61v377uvTRQQgMmirLNmjXL7rvvvsRd7rbbblatWjWrVauWNWrUyLbYYovEfn7hp59+al9++aWbffPNN23kyJFumkC9F+IVAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBIo8UD9ixAhr27ZtvmRXrVplF1xwgc2dOzdrf4X0BwwYkLUPK4tfoLgD9ZMmTbKBAwfmeSI1a9Y0VaBv3Lhxnn3V4YUXXrCzzz7b9SVQny8yOiGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIILBJCJRaoF6V6Dt16mTffPNNDF2vXj079NBDbe3atbZ48WJXtV4rCdTHRKU6UdKB+urVq7vz/fPPP1M+Jx5h2rRpVr9+fT+b8ZVAfUYaViCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIILBJC5RaoF4VwxV0VqtYsaJNnTrV6tatm3Ixli1bZoMHD7Zq1apRoT5FpnRmSjJQ37FjRxs2bFh8ov/5z3/s2WeftX79+tnq1avd8sqVK9ucOXOsfPnycb+kCQL1SSosQwABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFSCdS///77dtxxx8X6s2bNsn322SeeT5/4448/bOutt05fzHwJC5RmoN6f6rx589yTDfz89OnTrXbt2n428ZVAfSILCxFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEENjkBUolUN+rVy977rnnHP5JJ51kw4cPL/SF+OWXX2zChAn27rvv2ttvv21//fWXC1jXqVPH2rdvb/Xq1cu17x9//NFuuukmt1zB/hkzZrjjUaXzVq1auSroixcvtpEjR5rC/tWrV7fOnTubqur7VhT78Pv66aefbO7cufbSSy/Zxx9/bJ9//rmrwq6guM5D/zp16mQVKlTwm6S8fvnll+5YtbBRo0bWsmVLe+SRR+zVV1+NnwLQoEEDtw+dX7b29ddfO8+FCxfaggULnOXRRx9tp556qpvv27ev2/zmm2+2Dh06ZNtVgddNmjTJBg4c6LZLr1Af7uzggw82+auNGDHC2rZtG67ONU2gPhcJCxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAgEijxQP3ff/9tNWrUiPGnTJliRx55ZDxfkAmF6Hv06GHffPNNxs0GDRpkZ511lm222WZxn6VLl1qzZs3i+fSJFi1a2GuvveZC7eG6MLxdFPvw+95rr738ZMbXAw44wEaPHm177rlnrj4aSHDCCSe45d26dbPffvvNBepzdYwWXHnllaYBDUlt0aJFpu19WD3sU7FiRTv55JNt4sSJbnFpBuoVoNexqimAf84557jpTH8I1GeSYTkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAKbtkCJB+q/+OILa9iwYayuYPoWW2wRz+d34vvvvzdVXfdtp512cpXZt9pqK1dJ3Qeutf7GG290FdZ93/QwvKrkf/vtt66iu++j1zPOOMOWLFni9qf5Y4891saNG6dJK4p9uB1Ff3ygXqH1ww8/3FXE33HHHW3lypX29NNPxwF3rVfQf7vttvObutcwUO9XyKN58+a29dZb28yZM1MGHai/9h82hehV+d23ypUru/PVQARV6V+xYoVf5V5LK1C/du1aq1u3bjzYYezYse66pxxc2gyB+jQQZhFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDACZR4oH7+/PnWoUMH9+YKfb/11luFuhRDhgyxu+66y22r6u2TJk0y7U8tJyfHFPgeOXKkm1c4fM6cOVa+fHk3H4bh69evb9OmTXPLL7roInv88cfddLt27eyOO+5w+zr11FPt9ddfd8uXL19eZPtwO4r+dO7c2VR1/fjjjzcNCAjbn3/+aT179rTZs2e7xQMGDLDu3buHXSw9UK+BBgr++9D877//bh07drT33nvPbTd48GA788wzU/Zx22232fDhw92yevXq2X333RcH97W9Ktfr2vlWWoF6VcjXUwd803XR9c3WCNRn02EdAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACm65AiQfqFVhXcF1NQfhnnnmmwPq//PKLHXjggfF2zz77rNWpUyee14RC9arQrvC8msLiqkSvFgbqFVbv16+fW65Q/sCBA930dddd5yrUa0YV7u+88063/MMPP3Sh96LYh9thPv68//77dtxxx7meTZo0cYMHws3SA/UzZsyw/fbbL+xiMjr33HPdMoXjr7766ni9QvuHHHJIXPU9yTM8X21Y3IF6XbtLL73UHePff/9tX3/9tem8nnjiifi4L7jggrhPvDBhgkB9AgqLEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMBKPFA/ZswYu+GGGxx906ZNTRXHC9oWLVrkKrpru2yh/LCauaq6q7q7WhgO79u3bxw0V1hbIW01Behbt27tpkePHm1Dhw510wsXLrSdd965SPbhdpiPP2vWrLFatWq5njVr1jQFxMMWBuozeYTn3LJlSxs7dmy8i08++cRatGiRcf++Y/v27W3BggVuNj1Qr9D/unXrfNd8v26zzTZWrVo11z8c0JBtBxUrVjQNePADJLL11ToC9XkJsR4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNU6DEA/VTpkyxK664wmk3aNDAHn300QLLT58+3VRZXq1z5852/fXXJ+7jjTfesFNOOcWtC0PkYbj82muvtS5durg+qoDeo0cPN33PPffYMccc46YnTJhgV111lZuePXu27b333imB+sLuw+3wf//88MMP9sADD9hbb71lK1ascPsP1/vpPffc0+bOnetn3WsYqG/Tpo2NGjUqZb1mfvrpJzvooIPc8qOOOsomT54c95kzZ05cjV8hdVXzT2qqan/vvfe6VWGg/p9//rF99tknaZM8l9WvX9+mTZvm+uU3UK9BGa1atcpz374DgXovwSsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIhAIlHqgPw9tJ4fDw4DJN33333aYQu9oll1xiF154YWLXzz77zJo3b+7W1a5d2xTEVwsD9UOGDLFOnTq55bNmzbJu3bq56fvuu88aN27spu+//37r37+/m37xxRetRo0aRbIPt8Poz7hx41zFdT+f7TXJLAzUn3322TZo0KBcu/j111+tbt26bvlhhx1mDz/8cNxn6tSp1qdPHzd/7rnnmqr2J7WRI0faTTfd5FYVd6Begy26du3q3kvXa+bMmfbee+/Fh6WnHJx++unxfLYJAvXZdFiHAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDApitQ4oH6Tz75xFq0aBGLL1++PJ7O70QY7Fb4WyHwpPbFF19Yw4YN3aowiL4hBerDavs60Hr16lnbtm2tcuXKtu22npcofAAAQABJREFU28andcYZZ7hpLX/99dfj5ZoIA/XnnHOODRw4MGW9ZrIF6sPK8NkC9WHwPwzU5+Tk2OOPP25r167N9b55Ldhll12sadOmrlt4HB07drRhw4albB4G/7XilVdesapVq6b0SZohUJ+kwjIEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQKPFA/e+//2516tSJ5V966SWrXr16PJ+ficcee8wuvvhi1zVTgFwr33nnHWvXrp3r16hRI1OlebUNKVDfvn17W7BggTuufv36Wc+ePd10+OfHH3+0gw8+2C0qjkD9888/b3JU69y5s11//fVuOv3P0KFDbfTo0W5xGKhP71fY+bwC9dpv79697ZlnnnFvcdJJJ9nw4cPzfDsC9XkS0QEBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNUqDEA/VSVoV6VapX+/e//22XXXaZm87vH1VoVwVztZYtW9rYsWMTN33uueesV69ebl2nTp1syJAhbnpDCdSvWbPGatWq5Y6pYsWK9sEHHySeRzgwoDgC9e+99561bt3avbeqxU+cODHxOM477zx7+umn3brSCtQvW7bMmjRpEh/fjBkzbL/99ovnkyYI1CepsAwBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEESiVQ/+STT7ogvfh32mknmzdvnm211Vb5vhorVqwwVZz3bdGiRbb99tv72fg1rGbep08fUyBcbUMJ1P/yyy924IEHumOqXbu2TZ8+3U2n/+nfv39cXb84AvWrVq2y+vXrx2+rAP8OO+wQz2ti9erVtv/++8fLSitQrwPQtZw6dao7ljZt2tioUaPi40qaIFCfpMIyBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECiVQP0///xjzZo1MwXj1Y444ggbP368bbvttilXRP0efvhhUyX3rl27pqxThXpVqldTcP6KK65IWR9WXdeKV155xapWrer6bCiBeh2MQuoKq6uFx+gWRH8WLlxoJ510kp+14gjUa+fh4IMLL7zQLrnkkvg9NaHQ+rBhw+JlpRmo/+yzz6x58+bxscycOdP23XffeD59gkB9ugjzCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIICCBUgnU642fe+4569WrlyZdq1mzprVr187q1atn69ats48++shUyV7B+O7du9uAAQN8V/eqML1C9b6deeaZLniuUL5C6Kpi7lunTp1syJAhfnaDqVCvAwqD7Hvuuad17tzZmjZtahpMMHv2bLvxxhvj49ZEcQXqVZVe/r7p2hx//PG22Wab2TPPPJOrCnxpBup1jKFb27ZtbcSIEf7Qc70SqM9FwgIEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQiARKLVAv/Tlz5rhQva/QnumK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56LPfoUKFeL12tZXuE8P1KuTguAHHnhg3N9PlEag/r333jNdJzUF2v119MdUUq/hIJBBgwaZrntBmyr633333W4zAvVmK1asMIW31Tp16mRDhgxx0/n5o6eZaECH2gcffGD6jOenFVeg/sorr7QHH3zQHcKcOXPMv09+jmlD6aP/g+lJC2obY5X9DcWR40AAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEJFCoQP348eNNIVvfFJoMqwFr+a+//moKxs6bN8+eeeYZ35XXjVigJAP1YtJn7Mwzz8wlRqA+F0mJLnjiiSfsggsucO957LHH2rhx4xLff926dSlVwVWZffPNN0/sGy7s379/XHFZgeYWLVqEq+PpMBR7zTXXWNeuXeN1mSaKOlCve1x6OD7Te2dbroEHGoCg9uyzz1qdOnUSuycF6v/nf/7HVHE9vZVGoD68drpfHHXUUemHVSLzJ5xwgr399tvuvT755BM30KOgb0ygvqBimftvaIH6zEe68axRmF6herVevXqZ7oc0BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBwgkUOFD/559/2tFHHx1Xh7711lutffv2Gd9d1ey33nrrjOtZsfEIlHSgXpW/33jjDdtyyy1TkAjUp3CU+Ex+A/U6MFUrV9VytQULFtguu+ziprP90SCK2bNnuy4vvPCC1axZM7E7gfr/Y0lyKulA/V9//WX77ruvOyh9d998803bYost/u8gS3DKDzxQJXRVRC9MI1BfGLXkbQjUJ7usz9I1a9ZYrVq13C70OV+8eHGpfd/W5zzYFgEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDYEAQKHKifNGmSDRw40B37+oYmf/nlF5swYYK9++67rpqwApm1a9d21ZkV0q9Xr16i0ZAhQ0zb1q9f33777Td74IEHbOXKldasWTPr27ev/dd//Zepjyq4VqhQwVTBedCgQW653+F//vMfU1XrtWvXWvXq1V1163vvvddV1FeYd88997TDDz/c2rRpY02bNvWbZXxVFeQpU6a48LCCbWoNGjSwAw44wO171113Tdz2q6++sjFjxrh1GqjQsmXLXP0UnLvhhhssJyfH9tlnH+vSpUtK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6Dy892QbFNG0adN4v1999VXiKZflQL0Gs+W3+fvBxhyoj55WEF9vDSApyqZBft4oHOhVlO/BvhBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBTUFgM51kQcrkf/nll3b00UfHm0TBd6tTp048n9fEihUrrFGjRnG3RYsW2fbbbx/P+4kovG1RBWY326dPHzvvvPP8Ktt///1t9erV1rZtWxsxYoRb/uuvv1rdunXddBQys6h6vJv+6KOP7Nhjj3XTQ4cOtdNOO81NRyHnlOPWfrS/9BaF/i2q4J5rey2IwvZ28cUXu3X16tWzqFq1mw7/ROFt0zodr1pUudkaNGgQd4mqStuhhx7q5g877DB7+OGH43V+Iqpwb1G4M2OfqJq/nXDCCW59VDHcokrfftP4NfRJf59Vq1ZZFECN+77zzju2ww47xPOa0PHL3beoGq516NDBz67XaxQMt8aNG8f7ePPNN23XXXeN5zXx1FNPWTSAImWZZqIwoUVB83h569atLQqjuvmk89AKXSd9RnybN2+e7bHHHm526dKl1qxZMzcdBZKtU6dObnrWrFnWrVs3Nx1VpY+P9/7777f+/fu75VEVe6tRo4ab7tKli7388stuevDgwRYNVHDThf3z559/2n777ZeyeVQl2qJAcsqykpiJKrvbBRdc4N5K361x48ZlfdukYz/77LMtGmjitgs/v35H0WAVO/HEE/1s4uuVV15p0VMn3LooSG5R5e/EfuFCve8LL7zgFmX6zof9k6bDfYwcOdKikGxStwItO+KII+ybb75x22S7px588MEWVT93/UaPHm3RwISU94kC2nbUUUelLPMz8+fPt0qVKvnZIn/9/vvv43tbFGS36dOn5/keY8aMsWiAjOvXsmVL072uKJp3qlixokWDlgq1y6j6d/wZzc/9Lqokb9FAI/de+r3S71Z6W7JkibVq1SpeHFVHt3LlysXzfuL999+Pr23Hjh1t2LBhflWer7rXROFq1y8abGU77bRTrm30W6jPj1r0pBk78sgjc/VJXxDeG/Xd1Hc0vy38HZ0zZ47ttdde+drU96tZs2b8vU3fMLznR09lsPLly6d3yTWv3239fqtFAzmsevXqufr4BeH9qTC/r//884/ts88+fneW7fsdd8rnRHjf0O/etttum88t6YYAAggg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dZ8PPclk1113dZ/zPfbYI8/fKA1M0FNU9H8NDSjTYLzS/F0ry9eJc0MAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNR6DIAvUbG1mmQP3Gdh4cLwIIILChCTz11FN2/vnnu8PKVkl/QztujgeBDV1Ag//0dBI1PYVDT+OgIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIrJ8AgfrIL6xQv36cbI0AAgggsG7dOpszZ47pde+993aVtFFBAIH1F9BTbL744gtXlb5x48brv0P2gAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggYATqow8BgXq+CQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAwKYnQKA+uuYE6je9Dz5njAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIbLKB+j///NNOPvlk9wmoW7euDR06lE8DAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAwCYksMkG6jeha8ypIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCQIEKhPQGERAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQNkXIFBf9q8xZ4gAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQIECgPgGFRQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJlX4BAfdm/xpwhAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQIIAgfoEFBYhgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIlH0BAvVl/xpzhggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIJAgTqE1BYhAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFD2BQjUl/1rzBkigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIJAgQqE9AYRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBA2RcgUF/2rzFniAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJAgQKA+AYVFCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAmVfgEB92b/GnCECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAggCB+gQUFiGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgiUfQEC9WX/GnOGCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgkCBOoTUFiEAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUPYFCNSX/WvMGSKAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggkCBCoT0BhEQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDZFyBQX/avMWeIAAIIIIAAAggggAACCCCAAAIIIIAAArYcRs4AAAGnSURBVAgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggkCBAoD4BhUUIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACZV+AQH3Zv8acIQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECCAIH6BBQWIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCJR9AQL1Zf8ac4YIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCQIE6hNQWIQAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQ9gUI1Jf9a8wZIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCQI/D8AAAD//6zs0/QAAEAASURBVOx9Cdy2Q/X/vLy2JGu2bNn3nSxZ/4jImryWQkQiWxKVqGxZXllSilK0iLIrlD1lVxJF2uQNlcjW5vnPd36dq3PPM9c2M/d9X8/zfM/n8zzXdc8163dmzpw5c2Zm0oglQyICRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwwRCYRIP6CVbjLC4RIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACDgEaFDPhkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIHD00UebK6+80rzhDW8wd9xxh5k8eTKBaYHAfvvt53BbeumlzWWXXUb8WmBHr0SACBABIkAEiAARIAJEgAh0A4FxbVB/+eWXm4ceesghfcghh5jZZ5+9FvVHHnnE3HDDDc7fFltsYZZbbrnaMOPZwwUXXGBefPFF8/rXv97ss88+47moLBsRGCoC4Dvg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xLvjjju6Awimn376Hnf+qEeAfa0eo0H6oEH9INFmWkSACBABIkAEiAARIAJEgAgQASJABFoi8Morr5h3vvOdLtRKK61kTj755JYx0DsRIAJEoD0CDzzwgPn4xz/uAuKE3V133bV9JAxBBDqMAMfXDlcOs0YEOozAE088Ya699lpz1113mccff9xMmzbN5XaVVVYxSy+9tJkyZYpZc801O1wCZo0IEAEiQASIABEgAkRgIiLAOfBErHWWmQikIUD9cBp+4zk0Dhv4/ve/b2A8j3XLtdde22y99dY8WCCy0tnXIoHrUzAa1PcJWEZLBIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwvhEYGRkxkyZNGt+FZOmIABEgAkSACBABIkAEiAARIAJEgAgQASJABIjAOEeABvXjvIJZPCJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARCCNAg/owLnQlAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEIFxjgAN6sd5BbN4RIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIQRoAG9WFc6EoEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAuMcARrUj/MKZvGIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRCCMAA3qw7jQlQgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAExjkCNKj3KviRRx4xN9xwg3PdYostzHLLLef5GNzPl19+2UyaNMnMMsssg0v0vymNjIyYv/3tb2a22WYzkydPHnj6OsHnn3/eXHjhhc4J9YF6IY0tBL7xjW+Yxx9/3LXnI444YihtemwhxtzmRmDq1KnmxRdfNLPPPrs55JBDckffmfjAL4855phgflZccUWz3377Bb8NwrFL4+sgyss0uo3At7/9bXPHHXcEM4lxapFFFgl+67fjeJZ5BsGH+1WvF1xwgRtDXv/615t99tmn381g3MT/1FNPmfPPP9+VZ5111qEMP25qlgUhAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIjD+EKBBvVenMMT58Ic/7FxPOeUUs8suu3g++vfz3//+t7nsssvMfffdZ+69917zxBNPuMQWWGABs/LKK5v3vve9BsYomhBm//33N6+99lrhPMMMM5jFF1/c/S222GJm6aWXNnPMMUfxPfSC8Pfcc4+54oor3POxxx4rvCGulVZayRx00EEuruLDgF6AwyabbOJS22GHHcxnP/vZAaXMZHIh8J73vMfceuutLrr777/fzD333LmiZjxEoBECyy+/vHnppZdc20MbHK8E48V11103WLyNN97YfPWrXw1+G4TjMMfXQZSPaYwtBD72sY+Ziy++OJhpyEKrrbZa8Fu/HcezzDMIPtyvel199dXNX/7yFzPrrLOaX/ziF/1uBuMm/gceeMBsv/32rjz77rtv6YavcVNgFoQIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEYswiMC4P6c845x5x66qmuEnAS9vrrrx9dIcMy+HvuuefMBz/4QXP77bdX5n277bYzZ511VuHn1VdfNcsss0zxu+zl+OOPN7vvvruZbrrpgl623HJLg9OD6+iAAw4wRx11VJ23rN/Hs3FZVqAGEFlsX6NB/QAqh0lUIjAIQ87KDAzo49///vdiPESS2ESAjVqgGIP62D7vEvT+DWt89bIx5n/mrJMxD0ZCAa6++mq3gVCigPwlGxnbGtTffffdZuedd3ZRHXbYYebQQw+VaFs/x7PMMwg+nLNedeXFGtSPp/66xx57FPOURx99tNFtQzSo162I70SACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiECXERgXBvVnnnmmmTp1qsP5oosuMhtuuGE05pdffnlhCIWT0HEier8JxlO77babmTZtWpHUKqusYtZaay3zr3/9yzz4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2HoH6utxTFpzoL4ez9esY2gbjSpQmtfAMWve9957L54nuseosWO1xf6WaY5Affr5mnWPsL9B1Wg2bVOP+3A9nq9Z5rUcV7u88BzRdlZS6nG92mWEe5o+9XxrzqJe0MP69TulnFKPQH097sNhW6sN1NfrN48N1Msy/VzS9Wifbfr3WbFy2mmnxWMSjo3+rVduyTq3CNSXq0c9BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIG2JrCIdsiVWZKQmNtkk01cElj1c2y11VYuCem6Lbfc0r377rsuCae5G264oWBpe+21l/vTn/5UMC7padAlAQE/LglauBVWWKFgur6ceeaZLgmh+fFJWNF17969UZ0wIunh2W2zzTbhq+vTp49LAj+uU6dObpFFFnGLLrqo69Wrlx+OlZKB999/3yU9P9tR7p577nGXXXaZH5f0xOh+/OMfF0zv0qWLW3HFFQvG1frljjvucIcddlhczMYbb+ySwIW31rY/+eSTLgnRR/fjjz/eJQ0HfP0kIO3WX3/9OO/AgQNdEmR1c+bMcUkDiDiPKiy99NIu6anT6bjZouO54YYb2lH+uBaMSH3Zeuut3R577JEaW/vXpJGG0zlhSxJcdknDDD9K256EHu1kt9JKK7nOnTu7F1980R9nTUx6qnZ77723r/f3v//d7bfffn44CQC5Hj16+OGkx2KXBIH9cBK4cjq29ViGX2Dy59BDD3VJgwb/NQm5uFNOOcV973vfc9qfpDdX9+abb4aq/pikr53p06e73Xff3dfRuXjSSSfF+mHg448/dl27dvVfZZNexty5c/21E65ZHbfDDz/caXt07ic9bvp91gJkqPO/Xbt2YfGNPqu91upxzSc9BsfzQBum46trfc0113RJIxSXhJJcErpySejJn/e6H2l/s8rBBx/s7r77bj/p4YcfdquttlpWtUbjdN0lvYj78TLU9aZ7je6NuqedddZZBfOsssoq7tFHHy0Y98ADD7h99923YFzS4MBfTx06dHA6X+09U/ej9H2oYObki90fTdO1nvRO6hZffPF01bp9nzlzpttll13i8pIAluvbt6+/jl566SU3cuRIvw2xQjKQBMBdv3797Ch//DRi3XXXdUkAumBa+KLjnITg/Fedt+3btw+T/Keub7mp6LgkjRT88nQPHDFiRDzHNV3Pm/Q9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LL300u6xxx5zyy67bIvtHytGYEES0NsbFEb90Y9+1OjNIOodeOedd/abuzBdOwrPH3fccfEwTZw40W2++ebxOwMIILDgCHz99ddu1KhR7oILLvAbRQOYBefYVLMl9QzU640rBx10kPvHP/7hN2Xw4MHuiCOOqGazmAcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEgEC9ZwGCCCAQDMK1CNQf+utt7onnnjCh6jUO2koxxxzjDv66KPDVz4RWOgFxowZ48455xy3yiqruL59+7rOnTu7hoYGp17aQ8/0QhoxYoQbOHDgQuFl32ixww47uCuuuGKh2G92EoHWJDB69Gj35ptvusmTJ8ee6bX9V199tdt2221b066wrUag1kD93Llz3ciRI90HH3zg9FswFDUKmzp1qlt++eXDKD4RQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoEIBAvUVglEdAQQQqEWgHoF69S6tXqZt+cUvfuGDw4sttpgdzTACC7VACNQXQzjwwAPdCSec4Nq1a1esWpuZNn78ePfqq6/6/dlzzz3d+uuv32b2jR1BoK0IqCd6BeptOfPMM13//v3tKIZbmUCtgfrXXnvNbbfddgV7rTD9tdde6zbZZJOC8XxBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgcoECNRX5kVtBBBAoCaB6dOnu2HDhvllqEfsasJxCgnfddddTuH5rl27uq222sr16dNnoQkE13QAmHmhElBP9Lfffrt77LHH3AsvvBADqt26dXPrrbee+/Wvf+222GKLhcqEnUUAgQVf4IADDnBvvfWW69Chg9tyyy1dz549Xffu3Rf8DWcLiwoMHjzYzZw50/9+mzhxYsW/29599103aNAgv44VVljB/ehHP3K77LKLW2eddYqul4kIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUFqAQH1pI2oggAACCCCAQBsRaGhocIssskgb2Rt2AwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoFYBAvW1CjI/AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCA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NAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECtAgTqaxVkfgQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFWKUCgvlUeNjYaAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoFYBAvW1CjI/AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQKsUIFDfKg8bG40AAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQqwCB+loFmR8BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgVQoQqG+Vh42NRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEKhVgEB9rYLMjwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINAqBQjUt8rDxkYjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII1CpAoL5WQeZHAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQaJUCBOpb5WFjoxFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQRqFSBQX6sg8yOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0SgEC9a3ysDXfRn/99dfuoYceci+++KJ766233LfffutXvtFGG7k99tij+TakzmsaOXKk+/TTT91yyy3njjrqqDovPX9xkydPdjNnzvQVBg0a5NefX7vppowdO9bv/zLLLOMOOOCAplsRSy5bYEE5N8re4AW84rx581y7du1c+/btF/AtLdy84cOHu3feeadwZPJt8cUXd+eee26j8YxAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIHaBCoK1L/++utu2LBhmWvs2LGjW3vttd1aa63ldtxxR6egLqV1CyhEf/DBB7vnn3++0Y706dPHXXTRRY3G13vEmWee6WbPnh0Xe84557gVVlghfq92YMMNN3SfffaZX9Y///nPahdT8XzHHHOMmzhxop/v/vvvd507d654GfWYYbPNNnPvv/++W3rppd1zzz1Xj0WyjBoFFpRzo8bdaNHZn3nmGXfjjTe6xx9/PDZc2XTTTd1WW23lBgwY4NZcc80W3b5yVr799tu7V199NbPqK6+8kjmekQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUL1ARYF69ay9yy67lFybQrrHH3+822effdyiiy5asv6CUGHgwIFuypQpflNmzZrlllxyyQVhs1p0G/r37+/+8Y9/xG1Q+HuppZby33fYYQf3+9//Pk5rigEF3hV8t+W8885z/fr1s6OqGiZQ33KB+gsuuMCdffbZ/rhdffXVbtttt63qGLb0TF999ZXr0qWL3wwFtm+44YaaNolAfU18/k0aeubkFTXEueqqq9wPfvCDvCoLxPjzzz/fvffee3FbrrjiijhMoD5SMIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBA3QRqCtSH3rW//vrrzB51TzrpJHfggQfWbWObckF77rmn79VY61CP3WoUsDAX9U7fq1cvT7DGGmv4XtW/+93vNivJ3Xff7XvItyutV8/4LRWoP+GEE5xC5CoPPfRQi/WYHXrB1rENDUmsc1MOjx492o0cOdKv4sorr3Q9evRoytU12bK//PJLt+666/rld+vWzd166601rWtBOTdq2okWmvnhhx92e++9d1z7Kqus4nr37u3mz5/v7rjjDv82Ck3UfV3HKTSEiDMswAM77bRTfEsIgfoF+ECxaQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAq1WoOpAvQKLjz76aNzxb775xk2fPt2dcsop7l//+lccf++998bQaRy5AA4QqC88KAp7h96ejz32WHfUUUcVVmiGb+oB//rrr2+0ptmzZ7sOHTo0Gl/JiJYK1FeyjW21LoH6tnpkW26//u///s89+OCDfgP0tgD1RN++fXv//cMPP3S77bZbbPQ1aNAgd9ppp7Xcxla4ZgL1FYJRHQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIEKBeoWqA/rfffdd13Pnj1jj8Cnn366U9hxQS8E6guP0E033eQUpFc544wz3IABAworNPE3vfVgk0028efRCius4H7xi1+4Sy+91K/1iiuucDvssENNW0Cgvia+mmYmUF8THzOnBF5//XW3zTbbxLH//Oc/ne4ZtsyYMcP17dvXj1Iv9U8++aRbcsklbZUFdphA/QJ7aNgwBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBNiJQ90C9XGzP4gMHDnQjRozI5Jo7d64bN26ce+aZZ3zv9l988YX7wQ9+4DbaaCO3xx57uG7dumXOp5ETJkxwc+bMcYsssogbMmRIZjjynnvucVOmTPHL2H///d1aa63lh/Vn1KhR7u23347fb7311tgIQOHtJZZYIk7TQJcuXdyBBx5YMM5++fzzz32vyE8//bR76qmnfG/I2pcf/vCHrl+/fu5HP/qRrd5kww888IC76667nAKkelOA3iSw2WabuU033dTtu+++sdfm9AaoR/o77rgjjp41a5Y/Jhqh46AAui0a179/fzuqrsPTpk1zv/zlL/0y99prL9/DdAj1q4GGGmqUKpMmTXJ6Q8IjjzzidG5tt912rkePHm7vvfd2G2+8cQzrK4Abyvvvv+/OPvts//VnP/uZu/vuu92dd97p3XbZZRc3dOhQb3vBBRe4v//9765z585O5/gBBxwQFlHwed999/n1F4z835fDDz/cderUKWuSH/ef//zHaT0q22+/vfvJT37ibrzxRvePf/zD75fGb7HFFn5/tG3FymWXXebeeuutRlW+853vuCOPPLLR+KwR4XrVufLSSy85WSmcvPbaa/vzvHfv3t63Xbt2BbPfcsstBQZPPPGEe/75530dBaHXXHPNgvqLLbaYP76LLrpowfjwRdd+eAvGCSec4LS+a665xul4h/E6vrvuuqu30T6GovPg8ccf98cuXKfajzXWWMPfd3TNqnHNqquuGmaJ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0+Wicsghh/jrwX8xfz799FO30UYb+THaJm1buqgxSF7jgnRdfU8H6vXWCIWAZZAXHFewW72zq7f3couuGTWY0XLTPcMXC9TbnsAVfNcxLLdoPWrco/tBuuic0LmnN06EhjjlLP+TTz5xul7UU716h7dF54B6jk+XWs+NsDw1pNF1qjd2pIvOBzVUyfOxb3LQudaxY8f0IgqC3KXuobrnan22zJkzJ/bWb8c31fAll1zi9F/6fNI1JXPdg0sVvdlD53k5z7j0snQc9Bx44oknCiapYYMaguhYVbv8O+64wzcM07LtdThmzJh4nyhYKV8QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKAsgYoC9WUtsYpK6uVZYX2FBLt06eKD0e3atStrSQ0NDT4srOCmeinefPPNy+ohu6yFV1FJPfMrlK1e0tUYYOWVV3bf//73M8OqVSy+rFm++OILp0CytkPh6PXWW88tv/zyZc3b1irNnTvXN3KYN2+e23TTTd2KK67Y1nax2fZHDU5eeuklp8YK7733nltmmWXcqquu6oPHSy21VLNtRz1W9M477/h90afuOepdv9x7Tj3WX+9l6Dx/4YUXnHpJVw/r2qfWdkzqafLWW2/56759+/aua9euFTX0qHU79Bx67bXX/Pk1f/58H6BfffXVa10s8yOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQBMJLBCB+ibaNxaLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECuAIH6XBomIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCLRlAQL1bfnosm8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuQIE6nNpmIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQlgUI1Lflo8u+IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOQKEKjPpWECAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQFsWIFDflo8u+4YAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQK0CgPpeGCQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJtWYBAfVs+uuwbAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQK4AgfpcGiYggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIItGUBAvVt+eiybwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK5AgTqc2mYgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCWBQjUt+Wjy74hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII5AoQqM+lYQICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAWxYgUN+Wjy77hgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJArQKA+l4YJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAm1ZgEB9Wz667BsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBArgCB+lwaJiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0ZQEC9W356LJvCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAArkCBOpzaZiAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg0JYFCNS35aPLviGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkChCoz6VhAgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBbFiBQ35aPLvuGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggkCtAoD6XhgkIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACbVmAQH1bPrrsGwIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECuAIH6XBomIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCLRlAQL1bfnosm8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuQIE6nNpmIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQlgUI1Lflo8u+IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOQKEKjPpWECAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQFsWIFDflo8u+4YAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQK0CgPpeGCQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJtWYBAfVs+uuwbAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQK4AgfpcGiYggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIItGUBAvVt+eiybwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK5AgTqc2mYgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCWBQjUt+Wjy74hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII5AoQqM+lYQICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAWxYgUN+Wjy77hgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJArQKA+l4YJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAm1ZgEB9Wz667BsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBArgCB+lwaJiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0ZQEC9W356LJvCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAArkCBOpzaZiAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg0JYFCNS35aPLviGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkChCoz6VhAgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBbFlioA/XDhw933377rVt55ZXdwQcf3OaO8+TJk93MmTP9fg0aNMgtt9xybW4fm3uHXn75ZTdt2jT36quvus8++yyu/je/+Y1bccUV43cGSgvMnTvXjRs3zlf8wQ9+4HbeeefSM1EDAQQQQACBNizQEs/Gpvo9rN+g+i2qome8nvWU/wpMmjTJzZgxw3856qij+I1e5MTQb+7we3G77bZzO+64Y5HabX/S9OnT3eWXX565o7vvvvtC75MJU8XIsWPHuk8//dQts8wy7oADDqhiCZXNsiDch5vyWuN/l6jsfKA2AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0jEDZgfqrr77aB4nDZvbr18/16NEjfI2fX3/9tRsyZIj7//bOA16PqszDJ5RIERWJAiEsRVEEWRAIC1ICiIjSRTpSliaKrMCClAQEQZEWCJHFDS4aCEgXWBBEQJpLU9oidUEBDVUpAiEY7p7/Wd7Z95s785X55t773eR5f79kyjlz5sxz6tzvf96ZNWtWdu473/lOTwpFllpqqZTH5ZZbLvzqV7/K8ju77Bx44IHhsssuS49z0003hWWXXXZ2ebQheY5JkyaFU045pfDe1113XVh++eULw+o6KWHaiSeemCW3/vrrh9122y07Hm47Tz75ZNhggw1SttWfnHbaacPtEYYsv7fffns4++yz277/UUcdFZZZZpnUh5955pnpurXXXjvstddebaXx0EMPhZNPPjnFXWWVVYLEfzLlQXlpx+aZZ54wZcqUflHPOOOM8Lvf/S6d18KUsWPH9ovT6sT1118fNEa1a0sssUSQcMnsxRdfDIceeqgdttzusMMO4Qtf+EKKd+GFF4Y77rgju0Ziv2222SY7zu/ovi+//HI6rYVOK6+8cj4KxxCAwBxMYCjGxoGaD1900UXhkEMOSaWp+cv2228/B5ds46MfcMAB4Yorrkgnb7755rD00ks3RuAoI6Ax1urOfvvtl94zs8A5cOfKK68M3/zmNwuf/Igjjgj77rtvYRgnOyOw6qqrpvnaggsuGH7/+993dnGF2L3QDw9kW+PvEhUqBZdAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAKDTqBtQb3/EVS5lJj3pz/9ab8M33bbbWHnnXduOP9f//VfYfTo0Q3neuFgoH647oVnUx58mSGo765U7rzzzrDddttliUhcIYGy2VlnnRWWXHJJOxyQrQTnEydOzNJefPHFg9rWiBEjsnMDvTN58uRw0kknpdtIwCxRdlUbCtFg1bz22nVepNhO3n7+85+Hz3zmM0n4baK0cePGhalTp7ZzeZAn3W9961sp7i677BKOP/74tO/7mHYS+uMf/9gvmrx+2oImieu32GKLfnFanZCw/7vf/W6raFm4FhepTzR76qmn0phmx622XrD2r//6r+Hiiy/OLlHfoK9YaFtka665Zpg+fXoK0uKGTTfdtCjabHVOdebWW29Nz/TII4+E+eeff7Z6Ph4GAnUS6GZsrDpGD9R82I9VCOobawmC+kYezY4GUuTb7L69Gvbf//3fQW3LTH2GjbF+fmLhbKsRQFBf7+IV/87Qyd8l7rrrrrDtttumQlQa9j5SrVS5CgIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEBzApUF9UpWXoUXWWSRhjvIy6889npDUO9pDN7+4YcfnnltvuWWW4IJpgYvB7PPnbwIQN6+JQIebNtoo43C448/3nDba6+9NnzqU59qODeQB6effno49dRT0y3OPffcwq9UtHv/p59+Oqy77rop+k477RS+//3vt3vpHB/v6quvDhMmTMg4zJgxI7zxxhvZcb5fnjZtWqonEnJL0C37h3/4h0yAlV1YsuNFmuPHjw977713iikRu8T2ZuZ53Y59PkaOHNngyd3iDISg3t/X7uO3+iqJH6f+9Kc/hc0339xHybzI66TE8fPNN18WfvDBB2cLx/KCekVS2ZR5/58TBfUSQkkQJZOX17LFBikC/0FgDifQzdhYdYy2+WHdX2zyi7G0KFBfo8H+jwCC+vZrAoL65qz0lax99tknRUJQ35xVJ6F6R1F/3Ml8uZP083F7oR8eyLZW9e8S+juSvgwl23///bOvnuT5cQwBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgDgJdCerz3ibffvvt5AXZCzuVSQT1dRQVaQwlga222irce++9KQsStUscPJgmz97rrbdev1tqAcs3vvGNfucH6kRVsd5A5Yd0/4/An//857DWWmtlOIo8wSvw3XffbfiygjyzzzXXXNl1ZTtHHnlkOO+881Lwj3/846DFHUV2xRVXBIkEZRtvvHGYMmVKUbSGc3UL6r/61a+G4447ruEeVQ688P2aa64JK664YmEyRYJ6Cfp/85vfNIjw7WKf7pzioR5BvZU+WwgMLIGqY/RACTkH9mmHd+oI6tsvv4EU+bafi96NiaC+d8umk5z1Qj/ci20NQX0ntYi4EIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAtwQqCeo//elPB31u/rOf/Wy44IILsjzceOONYY899kjH8pr98MMPp30E9RkidoYpgVVXXTV5rJZnZXlYHmybOnVq5pH829/+dvjBD36QsrDyyiuHK6+8ctCyU1WsN2gZnENv1K6gXng23XTT1H9r/5577gkf+chHtNvUdt1113DzzTenOL/61a+CvBgXGYL6/6dywgknhB133PH/T7y3h6AeD/X9KgUnIFATgapjdC8IOWtCMGySQVDfflH1osi3/dwPfEwE9QPPeDDu0Av9cC+2NQT1g1H7uAcEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIGAEKgnqJ0yYEL773e+mNO6+++7w0Y9+NO0feOCB4bLLLgsbbrhhmDVrVibALBPU9/X1hauuuip58n3wwQeTyFOfVV9llVWSN+6vfOUrYcSIEZbXpttf/vKX4bbbbksi/oceeijIS76E/5/5zGeSqLHIu3D+h2stCLjpppvCr3/96/SJ99VXXz09y7777hvmmWeewvvPmDEj3HXXXUHX3nfffem6l19+OX0eXvfUwgJ55x09enTh9c8++2yYPHlyCtOn5b/whS+ESy65JDGRcFWmfOy0005hk002Scdl/91www3pawBF4fJivvDCCxcFNZz7+9//Hi6//PJULvJerU/dS0Su/H/iE58In//85xOTD37wgw3Xff/73w+vvvpq4v3666+HadOmheeffz5ssMEG4bDDDgvve9/7guJI9DHffPOFL37xi+Goo45K5xsSqvFAnuR/9rOfpXql+iUTS9WL3XffPau3RbccP358EAszv3CkSCR70EEHNU3P0qm61T3l8Vp2++23p0/em8f8O++8Myy22GJtJa22IQH+I488EsREdXXZZZdN9VTtbdy4cWHuuefO0pJAWu3XTAJscZVpQY21IQvXteobiryev/XWW2HixInJS7rFt+0//uM/hi222MIOm27rKFfVZ4nZqrR5y5zqx7HHHtvwPOr79G+wrRNBvRfx/ed//mdYaaWVUnbVZ6oNy/QFhlGjRqV9/ad2/OSTT6bjRx99tNDzugLndEH9+uuvn8YPsVh88cXTmJQfOwZaUK+vEKhtaxyTMEpj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)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f-mq1FCojI2p" + }, + "source": [ + "\n", + "## PDF Parsing\n", + "\n", + "We will go over five proprietary as well as open source options for processing PDFs. The parsing mechanisms demonstrated in the following sections are\n", + "- [Google Document AI](#gcp)\n", + "- [AWS Textract](#aws)\n", + "- [Unstructured.io](#unstructured)\n", + "- [LlamaParse](#llama)\n", + "- [pdf2image + pytesseract](#pdf2image)\n", + "\n", + "By way of example, we will be parsing a [21-page PDF](https://www.accessdata.fda.gov/drugsatfda_docs/label/2023/215500s000lbl.pdf) containing the label for a recent FDA drug approval, the beginning of which is shown below. Then, we will perform a series of basic RAG tasks with our different parsings and evaluate their performance.\n", + "\n", + "![image.png](data:image/png;base64,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)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lB0o4L4jh5Sv" + }, + "source": [ + "## Getting Set Up\n", + "\n", + "Before we dive into the technical weeds, we need to set up the notebook's runtime and filesystem environments. The code cells below do the following:\n", + "- Install required libraries (note - we assume a Ubuntu/Debian runtime below, but other environments will work as well so long as `tesseract` and `poppler` can be installed. Note that the exact names of the packages may vary. These are only needed for Solution 5.)\n", + "- Confirm that data dependencies from the GitHub repo have been downloaded. These will be under `data/document-parsing` and contain the following:\n", + " - the PDF document that we will be working with, `fda-approved-drug.pdf` (this can also be found here: https://www.accessdata.fda.gov/drugsatfda_docs/label/2023/215500s000lbl.pdf)\n", + " - precomputed parsed documents for each parsing solution. While the point of this notebook is to illustrate how this is done, we provide the parsed final results to allow readers to skip ahead to the RAG section without having to set up the required infrastructure for each solution.)\n", + "- Add utility functions needed for later sections" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZP1v0aF6Ij3U" + }, + "outputs": [], + "source": [ + "%%capture\n", + "! sudo apt install tesseract-ocr poppler-utils\n", + "! pip install cohere fsspec hnswlib google-cloud-documentai google-cloud-storage boto3 langchain-text-splitters llama_parse pytesseract pdf2image pandas\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "A5yWsKDSL_kY" + }, + "outputs": [], + "source": [ + "data_dir = \"data/document-parsing\"\n", + "source_filename = \"example-drug-label\"\n", + "extension = \"pdf\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "\n", + "sources = [\"gcp\", \"aws\", \"unstructured-io\", \"llamaparse-text\", \"llamaparse-markdown\", \"pytesseract\"]\n", + "\n", + "filenames = [\"{}-parsed-fda-approved-drug.txt\".format(source) for source in sources]\n", + "filenames.append(\"fda-approved-drug.pdf\")\n", + "\n", + "for filename in filenames: \n", + " file_path = Path(f\"{data_dir}/{filename}\")\n", + " if file_path.is_file() == False:\n", + " print(f\"File {filename} not found at {data_dir}!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BoM6-Tq-Sm-1" + }, + "source": [ + "### Utility Functions\n", + "Make sure to include the notebook's utility functions in the runtime." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "jl7BJsvdSrr5" + }, + "outputs": [], + "source": [ + "def store_document(path: str, doc_content: str):\n", + " with open(path, 'w') as f:\n", + " f.write(doc_content)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "R2u-drbt7SOQ" + }, + "outputs": [], + "source": [ + "import json\n", + "\n", + "def insert_citations_in_order(text, citations, documents):\n", + " \"\"\"\n", + " A helper function to pretty print citations.\n", + " \"\"\"\n", + "\n", + " citations_reference = {}\n", + " for index, doc in enumerate(documents):\n", + " citations_reference[index] = doc\n", + "\n", + " offset = 0\n", + " # Process citations in the order they were provided\n", + " for citation in citations:\n", + " # Adjust start/end with offset\n", + " start, end = citation['start'] + offset, citation['end'] + offset\n", + " citation_numbers = []\n", + " for doc_id in citation[\"document_ids\"]:\n", + " for citation_index, doc in citations_reference.items():\n", + " if doc[\"id\"] == doc_id:\n", + " citation_numbers.append(citation_index)\n", + " references = \"(\" + \", \".join(\"[{}]\".format(num) for num in citation_numbers) + \")\"\n", + " modification = f'{text[start:end]} {references}'\n", + " # Replace the cited text with its bolded version + placeholder\n", + " text = text[:start] + modification + text[end:]\n", + " # Update the offset for subsequent replacements\n", + " offset += len(modification) - (end - start)\n", + "\n", + " # Add the citations at the bottom of the text\n", + " text_with_citations = f'{text}'\n", + " citations_reference = [\"[{}]: {}\".format(x[\"id\"], x[\"text\"]) for x in citations_reference.values()]\n", + "\n", + " return text_with_citations, \"\\n\".join(citations_reference)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SULVG_HwKdm5" + }, + "outputs": [], + "source": [ + "def format_docs_for_chat(documents):\n", + " return [{\"id\": str(index), \"text\": x} for index, x in enumerate(documents)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y-VohvR3X6S6" + }, + "source": [ + "## Document Parsing Solutions\n", + "\n", + "For demonstration purposes, we have collected and saved the parsed documents from each solution in this notebook. Skip to the [next section](#document-questions) to run RAG with Command-R on the pre-fetched versions. You can find all parsed resources in detail at the link [here](https://github.com/gchatz22/temp-cohere-resources/tree/main/data)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jLtrGjXiJE9M", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "### Solution 1: Google Cloud Document AI [[Back to Solutions]](#top)\n", + "\n", + "Document AI helps developers create high-accuracy processors to extract, classify, and split documents.\n", + "
\n", + "External documentation: https://cloud.google.com/document-ai" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cxwJ_jZpgNDo" + }, + "source": [ + "#### Parsing the document\n", + "\n", + "The following block can be executed in one of two ways\n", + "1. Inside a Google Vertex AI environment\n", + " - No authentication is needed\n", + "2. Inside the notebook\n", + " - Authentication needed\n", + " - There are pointers inside the code on which lines to uncomment in order to achieve that\n", + "
\n", + "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "uZdjNlfxJEXv" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Extracted from https://cloud.google.com/document-ai/docs/samples/documentai-batch-process-document\n", + "\"\"\"\n", + "\n", + "import re\n", + "from typing import Optional\n", + "\n", + "from google.api_core.client_options import ClientOptions\n", + "from google.api_core.exceptions import InternalServerError\n", + "from google.api_core.exceptions import RetryError\n", + "from google.cloud import documentai # type: ignore\n", + "from google.cloud import storage\n", + "\n", + "project_id = \"\"\n", + "location = \"\"\n", + "processor_id = \"\"\n", + "gcs_output_uri = \"\"\n", + "# credentials_file = \"populate if you are running in a non Vertex AI environment.\"\n", + "gcs_input_prefix = \"\"\n", + "\n", + "\n", + "def batch_process_documents(\n", + " project_id: str,\n", + " location: str,\n", + " processor_id: str,\n", + " gcs_output_uri: str,\n", + " gcs_input_prefix: str,\n", + " timeout: int = 400\n", + ") -> None:\n", + " parsed_documents = []\n", + "\n", + " # Client configs\n", + " opts = ClientOptions(api_endpoint=f\"{location}-documentai.googleapis.com\")\n", + " # With credentials\n", + " # opts = ClientOptions(api_endpoint=f\"{location}-documentai.googleapis.com\", credentials_file=credentials_file)\n", + "\n", + " client = documentai.DocumentProcessorServiceClient(client_options=opts)\n", + " processor_name = client.processor_path(project_id, location, processor_id)\n", + "\n", + " # Input storage configs\n", + " gcs_prefix = documentai.GcsPrefix(gcs_uri_prefix=gcs_input_prefix)\n", + " input_config = documentai.BatchDocumentsInputConfig(gcs_prefix=gcs_prefix)\n", + "\n", + " # Output storage configs\n", + " gcs_output_config = documentai.DocumentOutputConfig.GcsOutputConfig(gcs_uri=gcs_output_uri, field_mask=None)\n", + " output_config = documentai.DocumentOutputConfig(gcs_output_config=gcs_output_config)\n", + " storage_client = storage.Client()\n", + " # With credentials\n", + " # storage_client = storage.Client.from_service_account_json(json_credentials_path=credentials_file)\n", + "\n", + " # Batch process docs request\n", + " request = documentai.BatchProcessRequest(\n", + " name=processor_name,\n", + " input_documents=input_config,\n", + " document_output_config=output_config,\n", + " )\n", + "\n", + " # batch_process_documents returns a long running operation\n", + " operation = client.batch_process_documents(request)\n", + "\n", + " # Continually polls the operation until it is complete.\n", + " # This could take some time for larger files\n", + " try:\n", + " print(f\"Waiting for operation {operation.operation.name} to complete...\")\n", + " operation.result(timeout=timeout)\n", + " except (RetryError, InternalServerError) as e:\n", + " print(e.message)\n", + "\n", + " # Get output document information from completed operation metadata\n", + " metadata = documentai.BatchProcessMetadata(operation.metadata)\n", + " if metadata.state != documentai.BatchProcessMetadata.State.SUCCEEDED:\n", + " raise ValueError(f\"Batch Process Failed: {metadata.state_message}\")\n", + "\n", + " print(\"Output files:\")\n", + " # One process per Input Document\n", + " for process in list(metadata.individual_process_statuses):\n", + " matches = re.match(r\"gs://(.*?)/(.*)\", process.output_gcs_destination)\n", + " if not matches:\n", + " print(\"Could not parse output GCS destination:\", process.output_gcs_destination)\n", + " continue\n", + "\n", + " output_bucket, output_prefix = matches.groups()\n", + " output_blobs = storage_client.list_blobs(output_bucket, prefix=output_prefix)\n", + "\n", + " # Document AI may output multiple JSON files per source file\n", + " # (Large documents get split in multiple file \"versions\" doc --> parsed_doc_0 + parsed_doc_1 ...)\n", + " for blob in output_blobs:\n", + " # Document AI should only output JSON files to GCS\n", + " if blob.content_type != \"application/json\":\n", + " print(f\"Skipping non-supported file: {blob.name} - Mimetype: {blob.content_type}\")\n", + " continue\n", + "\n", + " # Download JSON file as bytes object and convert to Document Object\n", + " print(f\"Fetching {blob.name}\")\n", + " document = documentai.Document.from_json(blob.download_as_bytes(), ignore_unknown_fields=True)\n", + " # Store the filename and the parsed versioned document content as a tuple\n", + " parsed_documents.append((blob.name.split(\"/\")[-1].split(\".\")[0], document.text))\n", + "\n", + " print(\"Finished document parsing process.\")\n", + " return parsed_documents\n", + "\n", + "# Call service\n", + "# versioned_parsed_documents = batch_process_documents(\n", + "# project_id=project_id,\n", + "# location=location,\n", + "# processor_id=processor_id,\n", + "# gcs_output_uri=gcs_output_uri,\n", + "# gcs_input_prefix=gcs_input_prefix\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "CT4QwMTwLPad", + "outputId": "1c85c3aa-a3b5-48c4-bb6e-5033c2c604a0" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'\\nPost process parsed document and store it locally.\\nMake sure to run in Google Vertex AI environment or include a credentials file.\\n'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "Post process parsed document and store it locally.\n", + "Make sure to run in Google Vertex AI environment or include a credentials file.\n", + "\"\"\"\n", + "\n", + "# from pathlib import Path\n", + "# from collections import defaultdict\n", + "\n", + "# parsed_documents = []\n", + "# combined_versioned_parsed_documents = defaultdict(list)\n", + "\n", + "# # Assemble versioned documents together ({\"doc_name\": [(0, doc_content_0), (1, doc_content_1), ...]}).\n", + "# for filename, doc_content in versioned_parsed_documents:\n", + "# filename, version = \"-\".join(filename.split(\"-\")[:-1]), filename.split(\"-\")[-1]\n", + "# combined_versioned_parsed_documents[filename].append((version, doc_content))\n", + "\n", + "# # Sort documents by version and join the content together.\n", + "# for filename, docs in combined_versioned_parsed_documents.items():\n", + "# doc_content = \" \".join([x[1] for x in sorted(docs, key=lambda x: x[0])])\n", + "# parsed_documents.append((filename, doc_content))\n", + "\n", + "# # Store parsed documents in local storage.\n", + "# for filename, doc_content in parsed_documents:\n", + "# file_path = \"{}/{}-parsed-{}.txt\".format(data_dir, \"gcp\", source_filename)\n", + "# store_document(file_path, doc_content)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dmkya9saFN8R" + }, + "source": [ + "#### Visualize the parsed document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "S6SMCDb1FhqZ" + }, + "outputs": [], + "source": [ + "filename = \"gcp-parsed-{}.txt\".format(source_filename)\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + "\n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dlRxuddi5w0E", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "### Solution 2: AWS Textract [[Back to Solutions]](#top)\n", + "\n", + "[Amazon Textract](https://aws.amazon.com/textract/) is an OCR service offered by AWS. It can detect text, forms, tables, and more in PDFs and images. In this section, we go over how to use Textract's asynchronous API.\n", + "
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1YCszLJnge4j" + }, + "source": [ + "#### Parsing the document" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vFBasw782Gho" + }, + "source": [ + "We assume you are working within the AWS ecosystem (from a SageMaker notebook, EC2 instance, a Lambda function, ...) with valid credentials. Much of the code here is from supplemental materials created by AWS and offered here:\n", + "\n", + "- https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/textract\n", + "- https://github.com/aws-samples/textract-paragraph-identification/tree/main\n", + "\n", + "At minimum, you will need access to the following AWS resources to get started:\n", + "\n", + "- Textract\n", + "- an S3 bucket containing the document(s) to process - in this case, our `example-drug-label.pdf` file\n", + "- an SNS topic that Textract can publish to. This is used to send a notification that parsing is complete.\n", + "- an IAM role that Textract will assume, granting access to the S3 bucket and SNS topic\n", + "\n", + "First, we bring in the `TextractWrapper` class provided in the [AWS Code Examples repository](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/python/example_code/textract/textract_wrapper.py). This class makes it simpler to interface with the Textract service." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "casiElly3G2C" + }, + "outputs": [], + "source": [ + "# source: https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/textract\n", + "\n", + "# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n", + "# SPDX-License-Identifier: Apache-2.0\n", + "\n", + "\"\"\"\n", + "Purpose\n", + "\n", + "Shows how to use the AWS SDK for Python (Boto3) with Amazon Textract to\n", + "detect text, form, and table elements in document images.\n", + "\"\"\"\n", + "\n", + "import json\n", + "import logging\n", + "from botocore.exceptions import ClientError\n", + "\n", + "logger = logging.getLogger(__name__)\n", + "\n", + "\n", + "# snippet-start:[python.example_code.textract.TextractWrapper]\n", + "class TextractWrapper:\n", + " \"\"\"Encapsulates Textract functions.\"\"\"\n", + "\n", + " def __init__(self, textract_client, s3_resource, sqs_resource):\n", + " \"\"\"\n", + " :param textract_client: A Boto3 Textract client.\n", + " :param s3_resource: A Boto3 Amazon S3 resource.\n", + " :param sqs_resource: A Boto3 Amazon SQS resource.\n", + " \"\"\"\n", + " self.textract_client = textract_client\n", + " self.s3_resource = s3_resource\n", + " self.sqs_resource = sqs_resource\n", + "\n", + " # snippet-end:[python.example_code.textract.TextractWrapper]\n", + "\n", + " # snippet-start:[python.example_code.textract.DetectDocumentText]\n", + " def detect_file_text(self, *, document_file_name=None, document_bytes=None):\n", + " \"\"\"\n", + " Detects text elements in a local image file or from in-memory byte data.\n", + " The image must be in PNG or JPG format.\n", + "\n", + " :param document_file_name: The name of a document image file.\n", + " :param document_bytes: In-memory byte data of a document image.\n", + " :return: The response from Amazon Textract, including a list of blocks\n", + " that describe elements detected in the image.\n", + " \"\"\"\n", + " if document_file_name is not None:\n", + " with open(document_file_name, \"rb\") as document_file:\n", + " document_bytes = document_file.read()\n", + " try:\n", + " response = self.textract_client.detect_document_text(\n", + " Document={\"Bytes\": document_bytes}\n", + " )\n", + " logger.info(\"Detected %s blocks.\", len(response[\"Blocks\"]))\n", + " except ClientError:\n", + " logger.exception(\"Couldn't detect text.\")\n", + " raise\n", + " else:\n", + " return response\n", + "\n", + " # snippet-end:[python.example_code.textract.DetectDocumentText]\n", + "\n", + " # snippet-start:[python.example_code.textract.AnalyzeDocument]\n", + " def analyze_file(\n", + " self, feature_types, *, document_file_name=None, document_bytes=None\n", + " ):\n", + " \"\"\"\n", + " Detects text and additional elements, such as forms or tables, in a local image\n", + " file or from in-memory byte data.\n", + " The image must be in PNG or JPG format.\n", + "\n", + " :param feature_types: The types of additional document features to detect.\n", + " :param document_file_name: The name of a document image file.\n", + " :param document_bytes: In-memory byte data of a document image.\n", + " :return: The response from Amazon Textract, including a list of blocks\n", + " that describe elements detected in the image.\n", + " \"\"\"\n", + " if document_file_name is not None:\n", + " with open(document_file_name, \"rb\") as document_file:\n", + " document_bytes = document_file.read()\n", + " try:\n", + " response = self.textract_client.analyze_document(\n", + " Document={\"Bytes\": document_bytes}, FeatureTypes=feature_types\n", + " )\n", + " logger.info(\"Detected %s blocks.\", len(response[\"Blocks\"]))\n", + " except ClientError:\n", + " logger.exception(\"Couldn't detect text.\")\n", + " raise\n", + " else:\n", + " return response\n", + "\n", + " # snippet-end:[python.example_code.textract.AnalyzeDocument]\n", + "\n", + " # snippet-start:[python.example_code.textract.helper.prepare_job]\n", + " def prepare_job(self, bucket_name, document_name, document_bytes):\n", + " \"\"\"\n", + " Prepares a document image for an asynchronous detection job by uploading\n", + " the image bytes to an Amazon S3 bucket. Amazon Textract must have permission\n", + " to read from the bucket to process the image.\n", + "\n", + " :param bucket_name: The name of the Amazon S3 bucket.\n", + " :param document_name: The name of the image stored in Amazon S3.\n", + " :param document_bytes: The image as byte data.\n", + " \"\"\"\n", + " try:\n", + " bucket = self.s3_resource.Bucket(bucket_name)\n", + " bucket.upload_fileobj(document_bytes, document_name)\n", + " logger.info(\"Uploaded %s to %s.\", document_name, bucket_name)\n", + " except ClientError:\n", + " logger.exception(\"Couldn't upload %s to %s.\", document_name, bucket_name)\n", + " raise\n", + "\n", + " # snippet-end:[python.example_code.textract.helper.prepare_job]\n", + "\n", + " # snippet-start:[python.example_code.textract.helper.check_job_queue]\n", + " def check_job_queue(self, queue_url, job_id):\n", + " \"\"\"\n", + " Polls an Amazon SQS queue for messages that indicate a specified Textract\n", + " job has completed.\n", + "\n", + " :param queue_url: The URL of the Amazon SQS queue to poll.\n", + " :param job_id: The ID of the Textract job.\n", + " :return: The status of the job.\n", + " \"\"\"\n", + " status = None\n", + " try:\n", + " queue = self.sqs_resource.Queue(queue_url)\n", + " messages = queue.receive_messages()\n", + " if messages:\n", + " msg_body = json.loads(messages[0].body)\n", + " msg = json.loads(msg_body[\"Message\"])\n", + " if msg.get(\"JobId\") == job_id:\n", + " messages[0].delete()\n", + " status = msg.get(\"Status\")\n", + " logger.info(\n", + " \"Got message %s with status %s.\", messages[0].message_id, status\n", + " )\n", + " else:\n", + " logger.info(\"No messages in queue %s.\", queue_url)\n", + " except ClientError:\n", + " logger.exception(\"Couldn't get messages from queue %s.\", queue_url)\n", + " else:\n", + " return status\n", + "\n", + " # snippet-end:[python.example_code.textract.helper.check_job_queue]\n", + "\n", + " # snippet-start:[python.example_code.textract.StartDocumentTextDetection]\n", + " def start_detection_job(\n", + " self, bucket_name, document_file_name, sns_topic_arn, sns_role_arn\n", + " ):\n", + " \"\"\"\n", + " Starts an asynchronous job to detect text elements in an image stored in an\n", + " Amazon S3 bucket. Textract publishes a notification to the specified Amazon SNS\n", + " topic when the job completes.\n", + " The image must be in PNG, JPG, or PDF format.\n", + "\n", + " :param bucket_name: The name of the Amazon S3 bucket that contains the image.\n", + " :param document_file_name: The name of the document image stored in Amazon S3.\n", + " :param sns_topic_arn: The Amazon Resource Name (ARN) of an Amazon SNS topic\n", + " where the job completion notification is published.\n", + " :param sns_role_arn: The ARN of an AWS Identity and Access Management (IAM)\n", + " role that can be assumed by Textract and grants permission\n", + " to publish to the Amazon SNS topic.\n", + " :return: The ID of the job.\n", + " \"\"\"\n", + " try:\n", + " response = self.textract_client.start_document_text_detection(\n", + " DocumentLocation={\n", + " \"S3Object\": {\"Bucket\": bucket_name, \"Name\": document_file_name}\n", + " },\n", + " NotificationChannel={\n", + " \"SNSTopicArn\": sns_topic_arn,\n", + " \"RoleArn\": sns_role_arn,\n", + " },\n", + " )\n", + " job_id = response[\"JobId\"]\n", + " logger.info(\n", + " \"Started text detection job %s on %s.\", job_id, document_file_name\n", + " )\n", + " except ClientError:\n", + " logger.exception(\"Couldn't detect text in %s.\", document_file_name)\n", + " raise\n", + " else:\n", + " return job_id\n", + "\n", + " # snippet-end:[python.example_code.textract.StartDocumentTextDetection]\n", + "\n", + " # snippet-start:[python.example_code.textract.GetDocumentTextDetection]\n", + " def get_detection_job(self, job_id):\n", + " \"\"\"\n", + " Gets data for a previously started text detection job.\n", + "\n", + " :param job_id: The ID of the job to retrieve.\n", + " :return: The job data, including a list of blocks that describe elements\n", + " detected in the image.\n", + " \"\"\"\n", + " try:\n", + " response = self.textract_client.get_document_text_detection(JobId=job_id)\n", + " job_status = response[\"JobStatus\"]\n", + " logger.info(\"Job %s status is %s.\", job_id, job_status)\n", + " except ClientError:\n", + " logger.exception(\"Couldn't get data for job %s.\", job_id)\n", + " raise\n", + " else:\n", + " return response\n", + "\n", + " # snippet-end:[python.example_code.textract.GetDocumentTextDetection]\n", + "\n", + " # snippet-start:[python.example_code.textract.StartDocumentAnalysis]\n", + " def start_analysis_job(\n", + " self,\n", + " bucket_name,\n", + " document_file_name,\n", + " feature_types,\n", + " sns_topic_arn,\n", + " sns_role_arn,\n", + " ):\n", + " \"\"\"\n", + " Starts an asynchronous job to detect text and additional elements, such as\n", + " forms or tables, in an image stored in an Amazon S3 bucket. Textract publishes\n", + " a notification to the specified Amazon SNS topic when the job completes.\n", + " The image must be in PNG, JPG, or PDF format.\n", + "\n", + " :param bucket_name: The name of the Amazon S3 bucket that contains the image.\n", + " :param document_file_name: The name of the document image stored in Amazon S3.\n", + " :param feature_types: The types of additional document features to detect.\n", + " :param sns_topic_arn: The Amazon Resource Name (ARN) of an Amazon SNS topic\n", + " where job completion notification is published.\n", + " :param sns_role_arn: The ARN of an AWS Identity and Access Management (IAM)\n", + " role that can be assumed by Textract and grants permission\n", + " to publish to the Amazon SNS topic.\n", + " :return: The ID of the job.\n", + " \"\"\"\n", + " try:\n", + " response = self.textract_client.start_document_analysis(\n", + " DocumentLocation={\n", + " \"S3Object\": {\"Bucket\": bucket_name, \"Name\": document_file_name}\n", + " },\n", + " NotificationChannel={\n", + " \"SNSTopicArn\": sns_topic_arn,\n", + " \"RoleArn\": sns_role_arn,\n", + " },\n", + " FeatureTypes=feature_types,\n", + " )\n", + " job_id = response[\"JobId\"]\n", + " logger.info(\n", + " \"Started text analysis job %s on %s.\", job_id, document_file_name\n", + " )\n", + " except ClientError:\n", + " logger.exception(\"Couldn't analyze text in %s.\", document_file_name)\n", + " raise\n", + " else:\n", + " return job_id\n", + "\n", + " # snippet-end:[python.example_code.textract.StartDocumentAnalysis]\n", + "\n", + " # snippet-start:[python.example_code.textract.GetDocumentAnalysis]\n", + " def get_analysis_job(self, job_id):\n", + " \"\"\"\n", + " Gets data for a previously started detection job that includes additional\n", + " elements.\n", + "\n", + " :param job_id: The ID of the job to retrieve.\n", + " :return: The job data, including a list of blocks that describe elements\n", + " detected in the image.\n", + " \"\"\"\n", + " try:\n", + " response = self.textract_client.get_document_analysis(JobId=job_id)\n", + " job_status = response[\"JobStatus\"]\n", + " logger.info(\"Job %s status is %s.\", job_id, job_status)\n", + " except ClientError:\n", + " logger.exception(\"Couldn't get data for job %s.\", job_id)\n", + " raise\n", + " else:\n", + " return response\n", + "\n", + "\n", + "# snippet-end:[python.example_code.textract.GetDocumentAnalysis]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kpF9UagY01-l" + }, + "source": [ + "Next, we set up Textract and S3, and provide this to an instance of `TextractWrapper`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "aetKe-lg0-58" + }, + "outputs": [], + "source": [ + "import boto3\n", + "\n", + "textract_client = boto3.client('textract')\n", + "s3_client = boto3.client('s3')\n", + "\n", + "textractWrapper = TextractWrapper(textract_client, s3_client, None)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U3Qr-MTL4dkT" + }, + "source": [ + "We are now ready to make calls to Textract. At a high level, Textract has two modes: synchronous and asynchronous. Synchronous calls return the parsed output once it is completed. As of the time of writing (March 2024), however, multipage PDF processing is only supported [asynchronously](https://docs.aws.amazon.com/textract/latest/dg/sync.html). So for our purposes here, we will only explore the asynchronous route.\n", + "\n", + "Asynchronous calls follow the below process:\n", + "\n", + "1. Send a request to Textract with an SNS topic, S3 bucket, and the name (key) of the document inside that bucket to process. Textract returns a Job ID that can be used to track the status of the request\n", + "2. Textract fetches the document from S3 and processes it\n", + "3. Once the request is complete, Textract sends out a message to the SNS topic. This can be used in conjunction with other services such as Lambda or SQS for downstream processes.\n", + "4. The parsed results can be fetched from Textract in chunks via the job ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "pb9AIE4v4Yww" + }, + "outputs": [], + "source": [ + "bucket_name = \"your-bucket-name\"\n", + "sns_topic_arn = \"your-sns-arn\" # this can be found under the topic you created in the Amazon SNS dashboard\n", + "sns_role_arn = \"sns-role-arn\" # this is an IAM role that allows Textract to interact with SNS\n", + "\n", + "file_name = \"example-drug-label.pdf\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "tPG-P7c79xln" + }, + "outputs": [], + "source": [ + "# kick off a text detection job. This returns a job ID.\n", + "job_id = textractWrapper.start_detection_job(bucket_name=bucket_name, document_file_name=file_name,\n", + " sns_topic_arn=sns_topic_arn, sns_role_arn=sns_role_arn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M0e0hZZJ-yCf" + }, + "source": [ + "Once the job completes, this will return a dictionary with the following keys:\n", + "\n", + "```dict_keys(['DocumentMetadata', 'JobStatus', 'NextToken', 'Blocks', 'AnalyzeDocumentModelVersion', 'ResponseMetadata'])```\n", + "\n", + "This response corresponds to one chunk of information parsed by Textract. The number of chunks a document is parsed into depends on the length of the document. The two keys we are most interested in are `Blocks` and `NextToken`. `Blocks` contains all of the information that was extracted from this chunk, while `NextToken` tells us what chunk comes next, if any.\n", + "\n", + "Textract returns an information-rich representation of the extracted text, such as their position on the page and hierarchical relationships with other entities, all the way down to the individual word level. Since we are only interested in the raw text, we need a way to parse through all of the chunks and their `Blocks`. Lucky for us, Amazon provides some [helper functions](https://github.com/aws-samples/textract-paragraph-identification/tree/main) for this purpose, which we utilize below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9h-6yBBJCYC-" + }, + "outputs": [], + "source": [ + "def get_text_results_from_textract(job_id):\n", + " response = textract_client.get_document_text_detection(JobId=job_id)\n", + " collection_of_textract_responses = []\n", + " pages = [response]\n", + "\n", + " collection_of_textract_responses.append(response)\n", + "\n", + " while 'NextToken' in response:\n", + " next_token = response['NextToken']\n", + " response = textract_client.get_document_text_detection(JobId=job_id, NextToken=next_token)\n", + " pages.append(response)\n", + " collection_of_textract_responses.append(response)\n", + " return collection_of_textract_responses\n", + "\n", + "def get_the_text_with_required_info(collection_of_textract_responses):\n", + " total_text = []\n", + " total_text_with_info = []\n", + " running_sequence_number = 0\n", + "\n", + " font_sizes_and_line_numbers = {}\n", + " for page in collection_of_textract_responses:\n", + " per_page_text = []\n", + " blocks = page['Blocks']\n", + " for block in blocks:\n", + " if block['BlockType'] == 'LINE':\n", + " block_text_dict = {}\n", + " running_sequence_number += 1\n", + " block_text_dict.update(text=block['Text'])\n", + " block_text_dict.update(page=block['Page'])\n", + " block_text_dict.update(left_indent=round(block['Geometry']['BoundingBox']['Left'], 2))\n", + " font_height = round(block['Geometry']['BoundingBox']['Height'], 3)\n", + " line_number = running_sequence_number\n", + " block_text_dict.update(font_height=round(block['Geometry']['BoundingBox']['Height'], 3))\n", + " block_text_dict.update(indent_from_top=round(block['Geometry']['BoundingBox']['Top'], 2))\n", + " block_text_dict.update(text_width=round(block['Geometry']['BoundingBox']['Width'], 2))\n", + " block_text_dict.update(line_number=running_sequence_number)\n", + "\n", + " if font_height in font_sizes_and_line_numbers:\n", + " line_numbers = font_sizes_and_line_numbers[font_height]\n", + " line_numbers.append(line_number)\n", + " font_sizes_and_line_numbers[font_height] = line_numbers\n", + " else:\n", + " line_numbers = []\n", + " line_numbers.append(line_number)\n", + " font_sizes_and_line_numbers[font_height] = line_numbers\n", + "\n", + " total_text.append(block['Text'])\n", + " per_page_text.append(block['Text'])\n", + " total_text_with_info.append(block_text_dict)\n", + "\n", + " return total_text, total_text_with_info, font_sizes_and_line_numbers\n", + "\n", + "def get_text_with_line_spacing_info(total_text_with_info):\n", + " i = 1\n", + " text_info_with_line_spacing_info = []\n", + " while (i < len(total_text_with_info) - 1):\n", + " previous_line_info = total_text_with_info[i - 1]\n", + " current_line_info = total_text_with_info[i]\n", + " next_line_info = total_text_with_info[i + 1]\n", + " if current_line_info['page'] == next_line_info['page'] and previous_line_info['page'] == current_line_info[\n", + " 'page']:\n", + " line_spacing_after = round((next_line_info['indent_from_top'] - current_line_info['indent_from_top']), 2)\n", + " spacing_with_prev = round((current_line_info['indent_from_top'] - previous_line_info['indent_from_top']), 2)\n", + " current_line_info.update(line_space_before=spacing_with_prev)\n", + " current_line_info.update(line_space_after=line_spacing_after)\n", + " text_info_with_line_spacing_info.append(current_line_info)\n", + " else:\n", + " text_info_with_line_spacing_info.append(None)\n", + " i += 1\n", + " return text_info_with_line_spacing_info" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McBARKH_ClEU" + }, + "source": [ + "We feed in the Job ID from before into the function `get_text_results_from_textract` to fetch all of the chunks associated with this job. Then, we pass the resulting list into `get_the_text_with_required_info` and `get_text_with_line_spacing_info` to organize the text into lines.\n", + "\n", + "Finally, we can concatenate the lines into one string to pass into our downstream RAG pipeline." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0CieHFURIhBm" + }, + "outputs": [], + "source": [ + "all_text = \"\\n\".join([line[\"text\"] if line else \"\" for line in text_info_with_line_spacing])\n", + "\n", + "with open(f\"aws-parsed-{source_filename}.txt\", \"w\") as f:\n", + " f.write(all_text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fy8iAFpbggcD" + }, + "source": [ + "#### Visualize the parsed document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "3AwZQnFRghv8" + }, + "outputs": [], + "source": [ + "filename = \"aws-parsed-{}.txt\".format(source_filename)\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + "\n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LEO2tP6WJmtn", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "### Solution 3: Unstructured.io [[Back to Solutions]](#top)\n", + "\n", + "Unstructured.io provides libraries with open-source components for pre-processing text documents such as PDFs, HTML and Word Documents.\n", + "
\n", + "External documentation: https://github.com/Unstructured-IO/unstructured-api" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "julG3fBrgmqQ" + }, + "source": [ + "#### Parsing the document\n", + "\n", + "The guide assumes an endpoint exists that hosts this service. The API is offered in two forms\n", + "1. [a hosted version](https://unstructured.io/)\n", + "2. [an OSS docker image](https://github.com/Unstructured-IO/unstructured-api?tab=readme-ov-file#dizzy-instructions-for-using-the-docker-image)\n", + "
\n", + "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5-jaa4-aJiJG" + }, + "outputs": [], + "source": [ + "import os\n", + "import requests\n", + "\n", + "UNSTRUCTURED_URL = \"\" # enter service endpoint\n", + "\n", + "parsed_documents = []\n", + "\n", + "input_path = \"{}/{}.{}\".format(data_dir, source_filename, extension)\n", + "with open(input_path, 'rb') as file_data:\n", + " response = requests.post(\n", + " url=UNSTRUCTURED_URL,\n", + " files={\"files\": (\"{}.{}\".format(source_filename, extension), file_data)},\n", + " data={\n", + " \"output_format\": (None, \"application/json\"),\n", + " \"stratergy\": \"hi_res\",\n", + " \"pdf_infer_table_structure\": \"true\",\n", + " \"include_page_breaks\": \"true\"\n", + " },\n", + " headers={\"Accept\": \"application/json\"}\n", + " )\n", + "\n", + "parsed_response = response.json()\n", + "\n", + "parsed_document = \" \".join([parsed_entry[\"text\"] for parsed_entry in parsed_response])\n", + "print(\"Parsed {}\".format(source_filename))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5qI5Q85vTfxs" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Post process parsed document and store it locally.\n", + "\"\"\"\n", + "\n", + "file_path = \"{}/{}-parsed-fda-approved-drug.txt\".format(data_dir, \"unstructured-io\")\n", + "store_document(file_path, parsed_document)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kOAYMvt1HlAj" + }, + "source": [ + "#### Visualize the parsed document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "cBr_roPTHonz" + }, + "outputs": [], + "source": [ + "filename = \"unstructured-io-parsed-{}.txt\".format(source_filename)\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + "\n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KF528hYyEQZx", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "\n", + "### Solution 4: LlamaParse [[Back to Solutions]](#top)\n", + "\n", + "LlamaParse is an API created by LlamaIndex to efficiently parse and represent files for efficient retrieval and context augmentation using LlamaIndex frameworks.\n", + "
\n", + "External documentation: https://github.com/run-llama/llama_parse" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oBLNlEVXgshj" + }, + "source": [ + "#### Parsing the document\n", + "\n", + "The following block uses the LlamaParse cloud offering. You can learn more and fetch a respective API key for the service [here](https://cloud.llamaindex.ai/parse).\n", + "
\n", + "Parsing documents with LlamaParse offers an option for two output modes both of which we will explore and compare below\n", + "- Text\n", + "- Markdown\n", + "
\n", + "\n", + "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "hR_85riD9ApM" + }, + "outputs": [], + "source": [ + "import os\n", + "from llama_parse import LlamaParse\n", + "\n", + "import nest_asyncio # needed to notebook env\n", + "nest_asyncio.apply() # needed to notebook env\n", + "\n", + "llama_index_api_key = \"{API_KEY}\"\n", + "input_path = \"{}/{}.{}\".format(data_dir, source_filename, extension)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "e4TskJQ4EdpA" + }, + "outputs": [], + "source": [ + "# Text mode\n", + "text_parser = LlamaParse(\n", + " api_key=llama_index_api_key,\n", + " result_type=\"text\"\n", + ")\n", + "\n", + "text_response = text_parser.load_data(input_path)\n", + "text_parsed_document = \" \".join([parsed_entry.text for parsed_entry in text_response])\n", + "\n", + "print(\"Parsed {} to text\".format(source_filename))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "GKca2BfI9X5O" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Post process parsed document and store it locally.\n", + "\"\"\"\n", + "\n", + "file_path = \"{}/{}-text-parsed-fda-approved-drug.txt\".format(data_dir, \"llamaparse\")\n", + "store_document(file_path, text_parsed_document)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Mjig7g-f89PQ" + }, + "outputs": [], + "source": [ + "# Markdown mode\n", + "markdown_parser = LlamaParse(\n", + " api_key=llama_index_api_key,\n", + " result_type=\"markdown\"\n", + ")\n", + "\n", + "markdown_response = markdown_parser.load_data(input_path)\n", + "markdown_parsed_document = \" \".join([parsed_entry.text for parsed_entry in markdown_response])\n", + "\n", + "print(\"Parsed {} to markdown\".format(source_filename))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "upmHMI8SLcXZ" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Post process parsed document and store it locally.\n", + "\"\"\"\n", + "\n", + "file_path = \"{}/{}-markdown-parsed-fda-approved-drug.txt\".format(data_dir, \"llamaparse\")\n", + "store_document(file_path, markdown_parsed_document)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P88GmKarHsTQ" + }, + "source": [ + "#### Visualize the parsed document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Y0Cs-a03Huob" + }, + "outputs": [], + "source": [ + "# Text parsing\n", + "\n", + "filename = \"llamaparse-text-parsed-{}.txt\".format(source_filename)\n", + "\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + " \n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "XW6SIVEg_fRN" + }, + "outputs": [], + "source": [ + "# Markdown parsing\n", + "\n", + "filename = \"llamaparse-markdown-parsed-fda-approved-drug.txt\"\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + " \n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8QQ_RopYZ_mf", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "\n", + "### Solution 5: pdf2image + pytesseract [[Back to Solutions]](#top)\n", + "\n", + "The final parsing method we examine does not rely on cloud services, but rather relies on two libraries: `pdf2image`, and `pytesseract`. `pytesseract` lets you perform OCR locally on images, but not PDF files. So, we first convert our PDF into a set of images via `pdf2image`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "unM8RfqYgzWC" + }, + "source": [ + "#### Parsing the document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "4kt-bmbGeWsf" + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\n", + "from pdf2image import convert_from_path\n", + "import pytesseract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5bE2Sebtf_eU" + }, + "outputs": [], + "source": [ + "# pdf2image extracts as a list of PIL.Image objects\n", + "pages = convert_from_path(filename)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ViLTaLPYeT-o" + }, + "outputs": [], + "source": [ + "# we look at the first page as a sanity check:\n", + "\n", + "plt.imshow(pages[0])\n", + "plt.axis('off')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZhXeNTbBKU_" + }, + "source": [ + "Now, we can process the image of each page with `pytesseract` and concatenate the results to get our parsed document." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "W1SNCEd91k7N" + }, + "outputs": [], + "source": [ + "label_ocr_pytesseract = \"\".join([pytesseract.image_to_string(page) for page in pages])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "tv9hLiJgBANJ", + "outputId": "1c3bd5dc-cfe9-43e6-9cc7-bc695a210d31" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HIGHLIGHTS OF PRESCRIBING INFORMATION\n", + "\n", + "These highlights do not include all the information needed to use\n", + "IWILFIN™ safely and effectively. See full prescribing information for\n", + "IWILFIN.\n", + "\n", + "IWILFIN™ (eflor\n" + ] + } + ], + "source": [ + "print(label_ocr_pytesseract[:200])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "TIwcDmjXejKV" + }, + "outputs": [], + "source": [ + "label_ocr_pytesseract = \"\".join([pytesseract.image_to_string(page) for page in pages])\n", + "\n", + "with open(f\"pytesseract-parsed-{source_filename}.txt\", \"w\") as f:\n", + " f.write(label_ocr_pytesseract)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j0u1UfNdaFt4" + }, + "source": [ + "#### Visualize the parsed document" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "HaJutaBkf9Yj" + }, + "outputs": [], + "source": [ + "filename = \"pytesseract-parsed-{}.txt\".format(source_filename)\n", + "with open(\"{}/{}\".format(data_dir, filename), \"r\") as doc:\n", + " parsed_document = doc.read()\n", + "\n", + "print(parsed_document[:1000])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SCbkT4oZSfs9", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "\n", + "## Document Questions\n", + "\n", + "We can now ask a set of simple + complex questions and see how each parsing solution performs with Command-R. The questions are\n", + "- **What are the most common adverse reactions of Iwilfin?**\n", + " - Task: Simple information extraction\n", + "- **What is the recommended dosage of IWILFIN on body surface area between 0.5 and 0.75?**\n", + " - Task: Tabular data extraction\n", + "- **I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of Iwilfin.**\n", + " - Task: Overall document summary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "WSo0xA4vZAHV" + }, + "outputs": [], + "source": [ + "import cohere\n", + "co = cohere.Client(api_key=\"{API_KEY}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gyPYqKErY7ni" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Document Questions\n", + "\"\"\"\n", + "prompt = \"What are the most common adverse reactions of Iwilfin?\"\n", + "# prompt = \"What is the recommended dosage of Iwilfin on body surface area between 0.5 m2 and 0.75 m2?\"\n", + "# prompt = \"I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of Iwilfin.\"\n", + "\n", + "\"\"\"\n", + "Choose one of the above solutions\n", + "\"\"\"\n", + "source = \"gcp\"\n", + "# source = \"aws\"\n", + "# source = \"unstructured-io\"\n", + "# source = \"llamaparse-text\"\n", + "# source = \"llamaparse-markdown\"\n", + "# source = \"pytesseract\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BwdK7trMKykt", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "## Data Ingestion\n", + "\n", + "\n", + "In order to set up our RAG implementation, we need to separate the parsed text into chunks and load the chunks to an index. The index will allow us to retrieve relevant passages from the document for different queries. Here, we use a simple implementation of indexing using the `hnswlib` library. Note that there are many different indexing solutions that are appropriate for specific production use cases." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "46rPn1uoLQDa" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Read parsed document content and chunk data\n", + "\"\"\"\n", + "\n", + "import os\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", + "\n", + "documents = []\n", + "\n", + "with open(\"{}/{}-parsed-fda-approved-drug.txt\".format(data_dir, source), \"r\") as doc:\n", + " doc_content = doc.read()\n", + "\n", + "\"\"\"\n", + "Personal notes on chunking\n", + "https://medium.com/@ayhamboucher/llm-based-context-splitter-for-large-documents-445d3f02b01b\n", + "\"\"\"\n", + "\n", + "\n", + "# Chunk doc content\n", + "text_splitter = RecursiveCharacterTextSplitter(\n", + " chunk_size=512,\n", + " chunk_overlap=200,\n", + " length_function=len,\n", + " is_separator_regex=False\n", + ")\n", + "\n", + "# Split the text into chunks with some overlap\n", + "chunks_ = text_splitter.create_documents([doc_content])\n", + "documents = [c.page_content for c in chunks_]\n", + "\n", + "print(\"Source document has been broken down to {} chunks\".format(len(documents)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "lk4YgREV7LgC" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Embed document chunks\n", + "\"\"\"\n", + "document_embeddings = co.embed(texts=documents, model=\"embed-english-v3.0\", input_type=\"search_document\").embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xtG3eblo7Mkd", + "outputId": "6dfb3a1f-d4a5-480b-b8e3-233950fce701" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Count: 115\n" + ] + } + ], + "source": [ + "\"\"\"\n", + "Create document index and add embedded chunks\n", + "\"\"\"\n", + "\n", + "import hnswlib\n", + "\n", + "index = hnswlib.Index(space='ip', dim=1024) # space: inner product\n", + "index.init_index(max_elements=len(document_embeddings), ef_construction=512, M=64)\n", + "index.add_items(document_embeddings, list(range(len(document_embeddings))))\n", + "print(\"Count:\", index.element_count)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YIncJz3qhWkg", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "## Retrieval\n", + "\n", + "In this step, we use k-nearest neighbors to fetch the most relevant documents for our query. Once the nearest neighbors are retrieved, we use Cohere's reranker to reorder the documents in the most relevant order with regards to our input search query." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5rTZcKQ48tAJ" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Embed search query\n", + "Fetch k nearest neighbors\n", + "\"\"\"\n", + "\n", + "query_emb = co.embed(texts=[prompt], model='embed-english-v3.0', input_type=\"search_query\").embeddings\n", + "default_knn = 10\n", + "knn = default_knn if default_knn <= index.element_count else index.element_count\n", + "result = index.knn_query(query_emb, k=knn)\n", + "neighbors = [(result[0][0][i], result[1][0][i]) for i in range(len(result[0][0]))]\n", + "relevant_docs = [documents[x[0]] for x in sorted(neighbors, key=lambda x: x[1])]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "vz8jbX8A9RO_" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Rerank retrieved documents\n", + "\"\"\"\n", + "\n", + "rerank_results = co.rerank(query=prompt, documents=relevant_docs, top_n=3, model='rerank-english-v2.0').results\n", + "reranked_relevant_docs = format_docs_for_chat([x.document[\"text\"] for x in rerank_results])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KX0RYtx1HW_h", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "## Final Step: Call Command-R + RAG!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "beUFAEKnHYCQ" + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "Call the /chat endpoint with command-r\n", + "\"\"\"\n", + "\n", + "response = co.chat(\n", + " message=prompt,\n", + " model=\"command-r\",\n", + " documents=reranked_relevant_docs\n", + ")\n", + "\n", + "cited_response, citations_reference = insert_citations_in_order(response.text, response.citations, reranked_relevant_docs)\n", + "print(cited_response)\n", + "print(\"\\n\")\n", + "print(\"References:\")\n", + "print(citations_reference)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lzJclPa6hnpi", + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "## Head-to-head Comparisons\n", + "\n", + "Run the code cells below to make head to head comparisons of the different parsing techniques across different questions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "52wdFoILLy85" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "results = pd.read_csv(\"{}/results-table.csv\".format(data_dir))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "l5WswlWbO4Da", + "outputId": "ddf65c9d-ef12-4b07-a000-b8c1e6c1319e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Question 1: What are the most common adverse reactions of Iwilfin?\n", + "Question 2: What is the recommended dosage of Iwilfin on body surface area between 0.5 m2 and 0.75 m2?\n", + "Question 3: I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of Iwilfin.\n", + "\n", + "Pick which question you want to see (1,2,3): 3\n", + "Do you want to see the references as well? References are long and noisy (y/n): n\n", + "\n", + "\n", + "\n", + "| gcp |\n", + "\n", + "\n", + "Compound Name: eflornithine hydrochloride ([0], [1], [2]) (IWILFIN ([1])™)\n", + "\n", + "Indication: used to reduce the risk of relapse in adult and paediatric patients with high-risk neuroblastoma (HRNB) ([1], [3]), who have responded at least partially to prior multiagent, multimodality therapy. ([1], [3], [4])\n", + "\n", + "Route of Administration: IWILFIN™ tablets ([1], [3], [4]) are taken orally twice daily ([3], [4]), with doses ranging from 192 to 768 mg based on body surface area. ([3], [4])\n", + "\n", + "Mechanism of Action: IWILFIN™ is an ornithine decarboxylase inhibitor. ([0], [2])\n", + "\n", + "\n", + "\n", + "| aws |\n", + "\n", + "\n", + "Compound Name: eflornithine ([0], [1], [2], [3]) (IWILFIN ([0])™)\n", + "\n", + "Indication: used to reduce the risk of relapse ([0], [3]) in adults ([0], [3]) and paediatric patients ([0], [3]) with high-risk neuroblastoma (HRNB) ([0], [3]) who have responded to prior therapies. ([0], [3], [4])\n", + "\n", + "Route of Administration: Oral ([2], [4])\n", + "\n", + "Mechanism of Action: IWILFIN is an ornithine decarboxylase inhibitor. ([1])\n", + "\n", + "\n", + "| unstructured-io |\n", + "\n", + "\n", + "Compound Name: Iwilfin ([1], [2], [3], [4]) (eflornithine) ([0], [2], [3], [4])\n", + "\n", + "Indication: Iwilfin is indicated to reduce the risk of relapse ([1], [3]) in adult and paediatric patients ([1], [3]) with high-risk neuroblastoma (HRNB) ([1], [3]), who have responded to prior anti-GD2 ([1]) immunotherapy ([1], [4]) and multi-modality therapy. ([1])\n", + "\n", + "Route of Administration: Oral ([0], [3])\n", + "\n", + "Mechanism of Action: Iwilfin is an ornithine decarboxylase inhibitor. ([1], [2], [3], [4])\n", + "\n", + "\n", + "| llamaparse-text |\n", + "\n", + "\n", + "Compound Name: IWILFIN ([2], [3]) (eflornithine) ([3])\n", + "\n", + "Indication: IWILFIN is used to reduce the risk of relapse ([1], [2], [3]) in adult and paediatric patients ([1], [2], [3]) with high-risk neuroblastoma (HRNB) ([1], [2], [3]), who have responded at least partially to certain prior therapies. ([2], [3])\n", + "\n", + "Route of Administration: IWILFIN is administered as a tablet. ([2])\n", + "\n", + "Mechanism of Action: IWILFIN is an ornithine decarboxylase inhibitor. ([0], [1], [4])\n", + "\n", + "\n", + "| llamaparse-markdown |\n", + "\n", + "\n", + "Compound Name: IWILFIN ([1], [2]) (eflornithine) ([1])\n", + "\n", + "Indication: IWILFIN is indicated to reduce the risk of relapse ([1], [2]) in adult and paediatric patients ([1], [2]) with high-risk neuroblastoma (HRNB) ([1], [2]), who have responded at least partially ([1], [2], [3]) to prior anti-GD2 immunotherapy ([1], [2]) and multiagent, multimodality therapy. ([1], [2], [3])\n", + "\n", + "Route of Administration: Oral ([0], [1], [3], [4])\n", + "\n", + "Mechanism of Action: IWILFIN acts as an ornithine decarboxylase inhibitor. ([1])\n", + "\n", + "\n", + "| pytesseract |\n", + "\n", + "\n", + "Compound Name: IWILFIN™ ([0], [2]) (eflornithine) ([0], [2])\n", + "\n", + "Indication: IWILFIN is indicated to reduce the risk of relapse ([0], [2]) in adult and paediatric patients ([0], [2]) with high-risk neuroblastoma (HRNB) ([0], [2]), who have responded positively to prior anti-GD2 immunotherapy and multiagent, multimodality therapy. ([0], [2], [4])\n", + "\n", + "Route of Administration: IWILFIN is administered orally ([0], [1], [3], [4]), in the form of a tablet. ([1])\n", + " \n", + "Mechanism of Action: IWILFIN acts as an ornithine decarboxylase inhibitor. ([0])\n", + "\n", + "\n" + ] + } + ], + "source": [ + "question = input(\"\"\"\n", + "Question 1: What are the most common adverse reactions of Iwilfin?\n", + "Question 2: What is the recommended dosage of Iwilfin on body surface area between 0.5 m2 and 0.75 m2?\n", + "Question 3: I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of Iwilfin.\n", + "\n", + "Pick which question you want to see (1,2,3): \"\"\")\n", + "references = input(\"Do you want to see the references as well? References are long and noisy (y/n): \")\n", + "print(\"\\n\\n\")\n", + "\n", + "index = {\"1\": 0, \"2\": 3, \"3\": 6}[question]\n", + "\n", + "for src in [\"gcp\", \"aws\", \"unstructured-io\", \"llamaparse-text\", \"llamaparse-markdown\", \"pytesseract\"]:\n", + " print(\"| {} |\".format(src))\n", + " print(\"\\n\")\n", + " print(results[src][index])\n", + " if references == \"y\":\n", + " print(\"\\n\")\n", + " print(\"References:\")\n", + " print(results[src][index+1])\n", + " print(\"\\n\")" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [ + "BoM6-Tq-Sm-1", + "jLtrGjXiJE9M", + "dlRxuddi5w0E", + "1YCszLJnge4j", + "LEO2tP6WJmtn", + "julG3fBrgmqQ", + "KF528hYyEQZx", + "oBLNlEVXgshj", + "8QQ_RopYZ_mf", + "unM8RfqYgzWC", + "BwdK7trMKykt" + ], + "provenance": [] + }, + "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.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/.ipynb_checkpoints/RAG_with_Chat_Embed_and_Rerank-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/RAG_with_Chat_Embed_and_Rerank-checkpoint.ipynb new file mode 100644 index 00000000..e138717e --- /dev/null +++ b/notebooks/.ipynb_checkpoints/RAG_with_Chat_Embed_and_Rerank-checkpoint.ipynb @@ -0,0 +1,873 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ctaLvRUsfpj8", + "metadata": { + "id": "ctaLvRUsfpj8" + }, + "source": [ + "\n", + " \"Open\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "61bac5b5", + "metadata": { + "id": "61bac5b5" + }, + "source": [ + "# RAG with Chat, Embed, and Rerank\n", + "\n", + "This notebook shows how to build a RAG-powered chatbot with Cohere's Chat endpoint. The chatbot can extract relevant information from external documents and produce verifiable, inline citations in its responses.\n", + "\n", + "This application will use several Cohere API endpoints:\n", + "\n", + "- Chat: For handling the main logic of the chatbot, including turning a user message into queries, generating responses, and producing citations\n", + "- Embed: For turning textual documents into their embeddings representation, later to be used in retrieval (we’ll use the latest, state-of-the-art Embed v3 model)\n", + "- Rerank: For reranking the retrieved documents according to their relevance to a query\n", + "\n", + "The diagram below provides an overview of what we’ll build." + ] + }, + { + "cell_type": "markdown", + "id": "CLNMDV4IuA3C", + "metadata": { + "id": "CLNMDV4IuA3C" + }, + "source": [ + "![rag-workflow-2.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACWwAAAL4CAYAAADlQyw0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAMfrSURBVHgB7N0LvF1lfSf8x4TcyUkgJCAJJjhcYrBE1Aj4ToUwSivWSajYy1uuM53O4LQFZjpjp50KWNsXWz8NaAdapyNXq1OxJGO9VC0B7QgSBYKCIVySSBIhISQ5ISc3Et7zX2EdVnb2OWfvc/ZZZ+99vt9+VvflrP3stdbeyXnk+eX/f8Or3RIAAAAAAAAAAABDblQCAAAAAAAAAACgFAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAAAAAAAICSCGwBAAAAAAAAAACURGALAAAAAAAAAACgJAJbAAAAAAAAAAAAJRHYAgAAAAAAAAAAKInAFgAAAAAAAAAAQEkEtgAAAAAAAAAAAEoisAUAAAAAAAAAAFASgS0AAAAA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RDLz6quvTp///OfTTTfdlAAAlqqIhyIuimL22267Lb3lLW9JME3Wrl1bxO/hzjvvTFdccUViNhVFIQpDAAAAYFEp2AIAxioSN/2WOoyOXPfee2+RlMxuvvnm4veRnAQAmDfXX3/9EUsebt26tYiH4paLYEJ8f9lllxWFW/E4mBbl9+kzzzyTAAAAABiegi0AYKyiYKvJUj533XVXuu666w4lfmLZoHicbhIAwLyJ+KZfjBPF7LfccksRH2VRsLVmzZp0zTXXJAAAAABgvixLAACLIAq7qh21brzxxgQAsNREMVcsMVftqHXttdce1pUUAAAAAJgPCrYAgEVT7TYR3SViaUQAgKUoumrddNNNh/0uOpICAAAAAPPFkogAwKKKTltRqJXFEomvf/3rBz4u7nf33XcXX6PIK5YMOvfcc9O6deuGXlYxthP7smnTpkNLNQ6z3eiEkQvPqo+J399xxx1H7PeGDRuKr6OI7cVSSrH/+fljm+vXr299TvodQz5HueNHPj/xWg6jfM5H3e+y2Fbs48aNGw+9nnlf4z026vkGgEmIrloxduXlEWOcjFubMbE8/o0rTiqrxgKx/RhbY+xuOr6WY414TNPH5fF90OMGxTLl+CDve78YNMee5WOOxwwb/+Rjidd569atR8Qqsc/xHE230+uc5L/FvreJs8rbrBP7W47hywa9x/JjqzGrGA0AAABYShRsAQCLavXq1Yf9PKjDViR3YunEXgmiEEme6FBx1VVXpSbiOWObt99+e9/nb7rdd7/73YcSXLG8USTyIjEVv++135GcjeRWLBPZNknV9JxcffXV6ZprrhmY/IvtXHbZZYd+PnjwYPE1EorR5SMnFOueo815j32++eabB57zpvudxfZuueWWgduO7cbSU5KCAEyb6LKVC7ZCjJlNCq0mESeVNRm7m8YzV1555aGYIvanuhxkLzHGx/1DPMfmzZtr73fxxRcf+v7BBx8sCoEGxTIRs8W5L+97vxguzsUw57Np7Nk0Vonjin0Mcf7vueee4vt8rno9R2w3YtW6QrXyea7T729xXHXno8n7M4jRAAAAgKXAkogAwKJ65plnDvu5X1FOJNiikGhQkicSa5Hoifv2SsiV7xsJvUHJx/J2I8HY777lv8XxRfFWPMeg/Y6/r127tkhkNRX3bXpOIrEW+zHonPR6nnJitddzxPkZ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SzmZGF8jmfihj3wonbTqpDROEoqUia+ASRJfUUd8xbx6+Y//TLE0YhRBbP21X0379+xOANPma5/6cNr1yEPpuDPOSq/6uZsTAAAwOQq2mBvHrlierrzxbcUSGrGUxqb/98/TA3d/QTcIYCR5iZ74TMnL9Hz3e99SfObAgQMHUlee3flsuuZ/veawZGJ8HTcJRcrEV8AkiK/oR3zFPHv1z99cFEHsfXRL2nzL+xRtAVPliU9/Mj11z6fTMStXFcValkIEAIDJOibBnIklNF7yitXpT+9+KG35/Lbidu7rz0qvftO5ac1LVyWAJp7c8nTasunR4jMkRALxDRtem1739lcnyJ5//vnUlZ/7334uPfznDxff3/J/3jKRZGLYf2B/girxFTAO4iuaEF8xz45eeVI6/wO/kb703r9/qGjrnB//x2n5S05LAIspOmtFsVY496ffl1Z82/kJAACYLAVbzKXz/sa56cwLTkt/etdD6ct/uOVQYnHlmhMWfn9GOv2cl6QVC9+vXLMiLT/ePwNY6vbt/VZ6fu++Iom44/GdadvDjxdL82TR9eENV1yo6wNH2PetfakLv/xLv5x+//d+v/j+Fz/wi+mC11yQJmXfvm6OidkjvgLaEF8xLPEV8y461pSLtr5yy/vSK6/5BUVbwKI4sGd3euxTd6Qd920sOmu9/B/803Tymy9PAADA5B11cEGCOfbNb+wqEouPfenJ4nuAJiJ5GInE6PggkUgvX/zyF9OkxRI9f/vyv33o51WrVqXzLzg/bfi+DemKK69Ik/Da816boB/xFTAM8RVNiK9YKp57/LGiaOu5x7el5aecls7+ofekla++MAF0Zd/TT6atv/arRfFoFGtFManOWsC8eeAdFxVfX/fBjydgtm37yK1p+/0b09qffn869a0bEswDl74z9048dWX6zh+7pPj+aw8/uXB7Ij3133csJBd3p2ef2pWe3+1KV1jqImF43Ipj00tevjq97ILT0imvOLn4CtNo586d6YE/fqC43fpvbk0f+siHJrZ8D/QivgIGEV8xS8RXLIbotPXaD/6H9JV//fNpx2c/UyyPePo73lncACZt56bPpUc/dms6sHvXwufRWUWxVnwuAQAA3dFhCwBgSF10gCh7duez6eGHH05333l3uus37yp+F8nEcScVdYAAABaL+Iql6LGP3Zq2LdzC8Wefm8758X9siURgImIJxMc//cn01D2fLn4++dLL07n/+P3pmJUnJYB5pMMWzA8dtphHyxIAAENZfky3yzmdtOqkdMlfuyT983/xz9NP/NRPFL+LJX1+7r0/l8Zl+XJLVAEAi0d8xVJ05g++J13wgQ8VXW5iabK/+BfvPVRMATAuux55KD3ygZ8tPl9iCcRX/PjPpFf9ws2KtQAAYJEo2AIAGNKyYxYvlPqJn/yJIrkYoitEdIcYh2OXH5sAABaL+Iql6qSL3lgsSRZXiu/fsyt97VMfTl+6/qfSvqefTACjiM+R//5rv1osvbrvqScXPm8uSRd+8D+kM674oQQAACweBVsAAEM64dgT0jg9/OcPp7vuvCv9/u/9fqP7X/KmFxKKkUzc9ti2NA5HLzs6AQAsFvEVS9lxZ5xZLO8Rt+i2FYUVX/qFnyqW/lC4BbQVyx8+8elPpkc+8N608wsPHOqqdcEHfqP4vAEAABbXMQkAgKEcf9zxaZw+8/ufSf/23/zb4vvf+czvpDPPaj6BOq4OECtOWJEAABaL+ApS0WXr5Ddfnh6/66Np28duTdvv31jcTn/HO9PJl65Py19yWgLoZ/t9G9MTv/3JovAzRFettde9X6EWAABMER22AACGNO6EYl6CJ0QniEEeuP+BQ99fcMEFaRzGfUwAAG2Ir+AFR688KZ35g+9JF932X4oCrhCdcr5yy/uKrzpuAXWiUCuWU9320VsPLX94wQc+pKsWAABMIQVbAABDWrli5ViXuImE4llnnVV8/5E7PpK2beu9DE8s6/PAH7+QUIyle05adVIaVRxLHBMAwGIRX8Hh8jKJr/3gJ4rCiyjAULgFVFULtWJZ1fjsiEKtky56YwJYqnKxau44CMyu51/8v88xK0f/vzpMi6NvWJAAABjKc88/l/Y+tzeNywWvuSDdfefd6fnnnj/09cyzz0yrVq0q/v7YtseKZOP7b3j/ocfc9pHbDv19FKtPWp1WnTj6dgAARiG+giMtP/nUotPWqm+/JD33xGNpz5ZH0q5HHkrb7/+D9PzXH0snvPzcdPQJigNhKTmwZ3d68nfvTlv/3a+mnX/yR8XPUaj1in/wM0Wx1opXjqdTJMAse/bPPpf2Pro5rTzvtToNwoyL5Z4j3nnZD/z94v9HMA+OOrggAQAwlF27d6Utj25J4xTL9fzce3/uiN9H0nDnzp2H/fyz/+xn04YrN6RxOPfsc3WAAAAWnfgKBnv2C59L2/7vWxe+/tUynie/aX1ac+n6tPLVFyZgfu1dGCN33PcH6ek/3pgOLIyZITrwnfrW7z20hCoAL3jsY7embQu3Uy57R3rZ9/9IAmZTdBb+0i/8VLF0/Bs+8YcJ5oWCLQCAET38Fw+n/Qf2p3GK5Xpu/eCt6TO/95nDkoghEomXv/Xy9J6ffM+hJX5GtXz58nTe2vMSAMA0EF9BM889/liRiPzG79196HfLTzktnf5d70wnnndhWv6S0xIw+6KbxDcfeSg9dc+ni+56WRRqnfX33mPZQ4Aeosj94ff+aNGJ9DW/8hsJmE0RA33tUx8uitOjkyjMCwVbAAAjeuKpJ9KTTz2ZJuVLf/6ltPPZF5KKq05alc4868x00qrxrtN+1kvPSmtWrUkAANNAfAXtROHWjs9+Jj1+98cWvt926Pe6bsFsi+KsZzd97rBuWsesXJVOedv3ppMvvVyhFkADX/ypH0i7//LhtPaaXxATwYz60vU/lfYtzBGc/4EPpVXiH+aIgi0AgBFF94dHvvLI2LtAdEX3BwBg2oivYHjRbWv7Z+8pCriy6Lp14qsuTKdc9l3p+LPPTcD0im5a33ixk1a1m9bJl16WTnnbhnTMyvEWGQPMs7wsYsRAr3rvBxIwW7bftzFt++it6bgzzkoX3fbbCeaJgi0AgDF4avtT6etPfj3NIt0fAIBpJL6C0fTquhXFW6u//ZK05tLvVLwFUyKKtJ6+795i6a5ykZZuWgCj27/r2fTFn/yBIh562ff/SDrlsnckYDbse/rJ9JVb3ld014qlEGNJRJgnCrYAAMZky1e3pF17dqVZovsDADDNxFcwHlEEEp23nv2zzynegikRicdnvvBAbZHWiRe9Mb10ww8p0gIYk/isffi9P1p8b2lEmA1R0B7FWnsf3VIUakXBFswbBVsAAGOyb9++9Jdb/3Jmlu5ZtmxZetU5ryqSigAA00h8BePXr3grlk1cc+l6SUyYkLzMYXW5wyjSOuHbzl9IRn5vWvPmyy15CDABeWnEo09YmdZe8/OK1WGKRbHWY5+6I+24b2OxFOL5H/iNha9nJpg3CrYAAMZolpbueelpL02nnHxKAgCYZuIrmJxexVshirbWvGl9OvG8C9Pyl5yWgPYi2RhdtHZ/+aH0zMK/swO7/6prZBRprX7zZWnVRW9UpAXQkc3/+ueL2CeKtl76/T+STr50fQKmSyyDuPXXfrXorKVYi3mnYAsAYMyeeOqJ9ORTT6Zpdvopp6fTTpF0AQBmg/gKJm/3X34pbb/vM2nHffcsfP/wYX/L3bdOWndJOuHscxRwQQ9RoLVnIbn47KbPpW/+xUNForEsko1RnHXypZcXHbUUaQF076u/9i/T1+/6aPH9yW9an07/7neKbWBKbL9vY/rab364KHJXrMVSoGALAGACtn19W9qxc0eaRmtWrUlnvfSsBAAwS8RX0J3nHn8sPftnD6Ttn70n7fnKl47ovhVLCEUB14rzLlTAxZJWLtDas23LYcschrzU4cmXXlYUakk4AkyHvDxiFoVbp1z2XZZJhEUQ8dTT991bdP/NsdRJF12S1l73frETc0/BFgDAhExjUlEyEQCYZeIrWBzRfaso4LrvnrRn4ftv7dp52N8juXnCWeekFa9+oYBLspN5te+pJ4vOWc99dWttB60QCcYVrzxfFy2AKRcF6lG4FUskZtFV9ISzzl2IZc5JwGRFXLVn29bD4qnoqnXmD/7DdOpbNyRYChRsAQBM0DQt32OZHgBgHoivYPHF1e+7v/JwzwKuZStWFgVcK199YXE74exz07ITViSYJbl7Vtyee/SFAq19NeOPAi2A2ZYLt579s88d0VUU6EbEU2ds+MF08psvT7CUKNgCAJiwp7Y/VSQV9x/YnxbDsmXLimTiKSefkgAA5oH4CqZLLuDauZDorFtCMZQ7VijiYto0Lc7KSxyu+vY3ppO+/RIFWgBzJrqKPv/EY2nXQlwDTFbEUCteeYF4iiVNwRYAQAf27duXNn91c9r3rX2pSytXrExnnXFWWr58eQIAmCfiK5he0akiCrd2/tkDaffC17ouXCF34opCrhXnXZiOfcmpllNk4vKyhvF176Nb055tW2qLs8KKb7sgnfTtbyw6aEWB1nFnnJkAAADGQcEWAECHduzckZ74xhMTTyzq+gAALBXiK5gNuWPFoCKuEEVbx77ktKIbV3x/9AkrdOSitSjC2rNta3r+qSeKrlnF908/mQ7s3nXEfaNz1rEvPTOdsPb8tPLF4qz4WbcHAABgUhRsAQAsgkklFiORGEnEU08+tfgeAGCpEF/B7CkvOxRFXPH97r/svQRRuSPXMaecmo495fSiK1d8Vcy1NJWLsr711DeKgqx+HbNCdMk64ZUXFF91zgIAABaLgi0AgEW0a/euIrm485s704EDB9IwInG46sRVac2qNcUSPQAAS5n4CmZf20KukIu5jj5hZdGZa/kppxVduqI7l4Ku2RWFV1GEFbf4Pm779+weWJQVqoVZK9ZeoGsWAAAwNRRsAQBMiUgu7n1ub9q1Z1eRXHx+3/Np377DO0QsX748HX300en4Y49Pxx/3wk0SEQCgnvgK5ksUcu3f9Wza/ZWH03NRxPWVF38eUMwVoqDrUAHXwtco6MpFXSH/jm7kYqvojrV/4TM6fj6we/eh4qz8u0FyUdbRK08qljI87oyzFn4+X8csAABg6inYAgAAAABgpj33+GPp+YXbc09sK74vfn7iscYFXVm5sCu6dcX3y1asKDp0Hf3i30Jxn4Wfde5K6cCe3Wn/7l1FkVV0v4qCq5CLsOL3LxRh7W5ciJVF4dXRJ65KJ6w9Px1z4klFp6xjVq5SlAUAAMw8BVsAAAAAAMy1b+16Nu35yy8V30eHrvi5XNS1/5s7i5+HEUVeucDr6BcLuHJhV/wuCr6K+71Y9JV/f3Sl2Cs/pmzUorBcTFUnF1aFXEyV5aKqXHBVvk/564Ee2x4kiq6OPvHEdOwZZ6VjTz+zKMY67vQozjqpWLowvirIAgAA5pmCLQAAAAAASC8Udj3/9ReLuIqirm3F7/a/WOAVX8PzC7/f/81vLvxtZ1rqcvFVyAVYIQqujll5UlF8Ffc59sWCLIVYAAAACrYAAAAAAGBoRUHXN1+8vVjQFUszhvjdt178XfztW9/8q+/zfbMoAqsatSisXExVFcVV2dFRWLVwy3JRVS64OrStF++Xf6f4CgAAYDgKtgAAAAAAAAAAADqyLAEAAAAAAAAAANAJBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0JFjEgAAAJRs2bIl3XHHHYd+Xr9+fXrLW96SAAAAAACA0SnYAgAAmDE7duwoCqo+//nPp3vvvbf4OW5r1qxJ5557bnGLAqsNGzYU37cV277hhhsO/Xz11Vcr2AKACYox/e677z70c4zfV111VRqn22+/PW3duvXQzxEnvP71r08AANOmeiHZIOvWrSvmRCK2ia8AMAsUbAEAAMyImLC88cYbi4RrnSjaioRv3O6666507bXXFsVW119//VCFWwBANzZu3HhYsXQ455xzxlYwHTHEu9/97iO2r2ALAJhG1QvJ2oj4KeZColu4uRAAppmCLQAAgBlwyy23FJOVUZTVRhR3xe3mm29O11xzTeJIcU6jwC3LHcoAoCvRTSsKrcuiiGtc41F05Ky64oor0lJVLn6PLhxL+VxMg3zBQRbvewl2AIYVcU+OfSK+irkQ4woMJ+bLynORETfrYgfjo2ALAABgykVXrX5XlsZESdzy0oh1YpIy/hbdtjhcJMTLXUdiInfz5s0JALoS43gUqZQLq6KoaFzjdnVJoaWcaIlzXO02dvDgwcTiiQsTykV0EfeKWQEYh7h4LQpObrrpJgXaMIQrr7zysJ9d5AjjtSwBAAAwtXoVa8UESUw4RmHR9u3bD32N22233VZ79Whsp5qwJRXnDAAWWzWJGMsY1nXGaqtuOxs2bEgAALMiCs3vueee2lvMgcR8R68ikoiFougk5lcAYJoo2AIAAJhSkVytK9aKjgNRoBVds6qFWTGJefXVVxd/r+tMEI+JyUoAYLrEsojVrlfRBXJU1WItSwACALMmdyOtu8UcSMx/RPFWzIX0u4gtujoCwLSwJCLQVyTzyl0Y1q1bN5ZJvWhBu2nTpkM/x6SkNcQBAA5XXa4nRFetKLpqIiYjY1LzuuuuO/S7WBYxriqNCUwAYHrEmP3617/+sAKrWMZn1KXhLIcIACwVkWeKAq4o5Iq5j/KSuyHmUyLPZUk3AKaBgi2gr5jUK3d1iGB3HAVbcRVD9QrPUScgAQDmSUwqVjthRbzUtFgri/tHd44omC9vOwq/JGsBYLrEBW3l+ZIotI6fh00qWg4RAFiKIpcVF6qdc845RyyFGBfHPfjgg+ZEAFh0lkQEAACYQtUJxZhsrFsesYkozqqyDAAATJ+67ld33313Gla1WGtcF+IBAMyCmEepxj5R0G5OBIBpoMMWAADAlInkal13rWFFcjY6c5STttFxa5RtRseP6Mb6+c9//rB9jaWc1q9fP7ZkcGw7EtXxPPGccQuRzI7javtceTtl5aW6s2qCuyqe25LeAIxbjG8xrpWX78mdMYdRXQ6xbaeuGDMjZoixMsbk8jicx/xxLyk0zuesG/fjd1XjHvcncd5iG3X73nRf4xgjpirvT+xLk/dWPDaOpRr3leOxOJ4mnUrqznU17q3rDFfV9vz1OoY4B/k1aRvb1b2/6sT2q+cmv0eiE255fyI+b3ps5Ti5+rrENuKY4rkBlrrotBXjQPkzO5advuaaa4bqstVrnA/lcX7cHbwm9blfHc+Gje3abqd8/7r4pe54cywVHWObHGtd/JPPV2xjXPM6OU6rPlcY9T0R2yu/3nXntV+cE8fZ5DVtGmvWzaGV5deo6fPVnbNJ/l8Dps5BgD5uuOGGg/FRkW8LwcvBcVgYYA/bbjwPAAAvuPrqqw+LleK2efPmg6NYmIw8Ypvbt2+vvW81Boz9yWI/qrFc3S3ixoUE88Fh3XPPPY2eJz9X7HOv4ylrsr0mN/ErAJMSY2B13InftRVj9rDbefDBB1uNw6OM+eX9jZhjIUEztrF/IdEzlnG/HAv1M0z80lRdfNhru232qZ+FBHercxj72C9mXUhuj+X1iFu8R5uIc9zkPRW3OE9Ntxvvvab7Wv73EY/rt09N3hNt3mfx+o3j3ydA18adm6puL2533nlnq23EGHfttdc2GlfiPoPGxabaxhdtPvfr4sVh9rluO4OOqXzfK6644rBtNTneeEyvfW16zuI1ajKX1MugcX0c74nqcZRjlabH2eR90TTWbPJc4zpnTfcdZpklEQEAAKZM9Yq2uJps1Kv+8pWW+arFYbYXXTouvvjigR0PQlwdtzDZk9797nentq677rp02WWXNXqe/FyxzEHsW7VDAwDMmrpuPMMsi1i3HGKTK9RjHG463oc85q9du3bocTiWJYrnjG5iTToWlcf+fvvZZFvjMmz8EuetSTeDYcQS2232qbxv8biI49rsW7x+cTy9lplaSNClcRn02sZ+x77EOW76PojzFO+peC0HPabNeyvfN85rbL/NPlW3E69Lm9c0zkOOycXJwFJW102rTXyVY5XozNXkMzzuE+NifGZXO542FdsYJr6Iz/14zCx97ud9jXGraRwaXc7iOKuxSpv4J16jYeeS4nVtE2uU3xOx78PKz9XmOPP7Ih6zmGJf28Zn4/i/BkwzBVsAAABTpK4F+TiWF4zk74MPPpg2b9586NamFXtMJsUESXVCJbbRbzsxGRUTjE1FMikmQKtyO/RINPdqI5+TiyZwAJhlMcbFmFtWXiKxqWGWQ+w1Dodc8NVvHI6EV9vio0gcXXvttT2TNvG8vWKNPPYPmwgdh9jvnMDtZdAxxOPHdQw5DorzGsmwtnJRUDX5l5cPivdmbDdes4hR6y4CiL/1KtrqQpzLfjFhXsqxl3gtByVv28TRcU5HjVPz+6QuKdskTs4JYnEysFTVLdPWtGgm5jQGxSq9xpVhC2XyuNErvshjWa/xKMaLWfrcz2PllVdeWTvv1Ev1MRF/1MU//cb92Ebbiw3j9aybI8vPlcfkuqUB8z4PWzwVz9krzhsUn8RjJh2j9dqH+D9CvCer5yzOV5zL+DeWY8y6/7eY82NeHZMAAACYGnVJznXr1qXFFJMh5aKrmDi5/vrrD+sAEhMuMdkZk0bVyZOYYNywYcPARHE8tpqQjue46aabah8bE5Ax0VSeZM0Tbffcc0/tc0ShWnX/Nm7ceNhEVxzTnXfemfqpm3QDgHGJcbOcoItxNsa9JkVXIca6amHHVVdd1fcxMX5Wx+FIoERHikiiVJMvEbPEOFx+TC72iSLxJt08eyWb4vlif8vHm4vaoxinup9x/3POOeeI8xPxQHXcj21Ui8l7xQ1Zv3G/rrNDnKs4bzlZVz6GHL9UX59cpNfrdYrYq+5vsc1I+pXl7l1lOWk4KK6sxnL5WCJ51isBF69H9XFx/9zhNYtjrHtfVOO5/Pr3Upd0z3JHqao4/thmFJmVjyPuH88d76vy/udkarw36o47ftfrfVM9npxYrZ7X2Jd4PcrxdJsEZY7Je8XJ8T4vvzcHHRPAvIvP3fL4m4uE+sUs8fldVzSVx6pqZ9TYfl2sksfl+Nxuou5zP4/J1fE0x33VsSaPHxGXzcLnfvmY6+ad4m855iiL38fYG69HOf6piyfr4teQX7dB8XKoi1/7xUu99ju2Ea9jk+csi85w5f2vey/2ek/k5437V/ezV6wZr0tZzNH1i417/Xuqxqv95vvyMVTP26A5P5hJBwH6GPc64Vl1TeV4HgAADh687bbbDouT4rYwuXawS9UYsHxbmEwZ+PiFSZ4jHhfxXz+bN28uYs3yYxYmig5u37594PMtTIgd8XwLkzcHm6qe83HFvAAwioUkymHjU4x3TbUd2+rG/qbj8J133nnEvg4a9+v2Me9nk7gnHlt9znhsk/2NGKH6vMOqO28LyacirhnmGOLnJo8ti/vXncf8/UISr9F5CXG/YePQeGwce9v3QYh9HMc8YV08Gee0Sfwaj11I5B9x/G3+3WXV4ymfl9i/eO1H2V7cIt5uoi4uH+aYALo2idzUXXfddcRnYsQxvYwSq9SNSU3nKurmOGKMajKe133ux2P77Wf1/m1jkV7b6acuHms6xsX5r4uh8jge3w86zxEbtJ236nWc8To3OWe94pRBj63mU8vPO+g46+KztrHWMO/hqrr/mzSNT+te737/bmHWKNgC+prWgq0YyGOAj8A1grDYXr7FJMbNN9889sRmBCGx3dh++fliH26//fbWQWwcQ2yzya3p/jQN2gGA6VWX+Ot6fO9VsNUk2ZXVTSj1O45RJm9CddJrkkltAOhCNVkXiYqmquNwzB30EvMZ1SRIv8RenbqkW8yV9FMdu5smu7KY9xkm+TSugq26hF0kxNrEL3X70rTIqd9+5FvbwqDq/rR9H9TtS5PzMa6CrbrCprbnIAoVR01M1u3HMO/xUFcs0LRYK6tL/A+TjAfo0iRyU3XjVK94pa64pu3neK9ttN3HtuNxXdFWr7Fs2gq2mo5xdQVXbcf+YcbHcbwnqnF3vzg99CrYavq8EYvVXejQVNP3Uj/Vovi28Vn186DtvwmYZgq2gL6mrWArJuN6BSd1t5goGzRBOEgURdVdCVF3i8CqaZBUN+HS69bmHAwTLAEA06OuWGoa9qFt8rBu8q3fFXDVyZuIwdqI+1fjwKYUbAEwjerG0ib/569LmPW7qK1aXDJMUUnddvqNxXVzIsNcKV+NWSIZNahAaFwFW+M6b3VxV5u5nV4FW22LekL1dRmUQKxTnbNqcizjKNiqOw/DnIO6pGbbOLiuYGvY90d1TnLYBOUoFzcALIZJ5KbqOkn2GnPqYpVhPsfbFrWPK76ojse9xrJpKthq8xrXjddtx+y64v9+r824OuLXFZv1i1/r8oFtY5y6eLPp6zxKnJoNEx+WVV/vNnN+MO2WJYAZEetKX3zxxYetMT5IrEcd6zfHmsaxHnkbsRZyPF+sOV1d47mXWE957dq1R6xFPar8/MOcAwCAcViYDGp1/4XJmLQwmXLY7zZt2tTz/ldddVVamEA6dNuwYUNqY2Fi77Cf28Z+ADBt6sbSu+++e+DjqveJMXIhqdHz/tU5hmuuueaIcbWJaqwQczK95i9ifqMsjvWKK65IbcW+ls9RjP/xvJMW8zQxB1QWscww5616DKHJ69xP7EfEU6NqOh9WtpCAiwztoVu8tl2ovqfinMacYFvxuJgLLIv38TDnoiz+fbR9f9Q9b7xfhlE9pur7F2ApqI63/VRzPDGmDDPOxzhYHQt7fQbXxRfDjB/5cWURH037PEmbWDBey7r7RzzWVMTH1XPbb7y/4447Dvs5nr9fjN1LjMnV92J124O0jXHqzksXMXPWZn6w1+O3b99+KL588MEHE8wLBVvATIjguDqxECIYisAkJ/bi+7oAKYLcyy67rHFAGoFKFEbVBSwRGMRzRJDdKxiLfYkisXGKY6g7BwAAkxbxzzDJtupj+sViMdEVE4r51nZCcvXq1QkA5s0wRRbV+/RLftUVhAxTOBXqCsPqkjHxfNX5ljbJtbKIUW677bbDir6HSWq2VVeINkxxUKgrLBq1mGbY17D6+sVxjvuixEmpviZxDoZ9L0yiiG6YWLqu+HLYArjqv7GuihsBZlF8Plbjo2FjlbrHxphVNz9SF18M+7kfjyvHSDHP0qZgbTGMeuFeaBsDVc9vr4KteL2qr0/b/S2rxn5tmjTEPreNceL+1df/mWeeSV2p7u/NN988cjE8zItjEsCUi0G7elVgBF033XRTz6AkHhMTSuUJrgiy43fxuEHPV1fcFQFUBNZ1ice77rqr2HY5wMjPHUFxnX5XZESxV3lbed/LcsHYOeeccyjQ2rp1a2dXLgIAS8cwVwyG6mSQrlcA0M769esP+zkni3r937+uGKpfR56NGzce9nNdp4E24vHl568rCKkr4hplLiPmiIYtUBpW9RhGPW+R8IvEVRavc7yWw25z2ARiPo7ynFTMycUcV8xjxfsxX8g4TeqKj0ZJouZjLCdP4/thu1sN+/6oHtMo/07imKqvbbyPp+21BJikNhf0V40aq1Qv8I+i3GohVzUuG6Ywp2zYYvLF0nZMitxYWYx1kypKq3tPjBJ/rlu3buD2exlljm6x5uWqsW7EI7FaUZzDeJ/H+YjjmvaiQpgEBVvA1KsWKsXkSHlgrxNBbBRKRcBWfnw8rt+VBBGsVIu18tWavYKvfCVk/D2ufC23Lo0JrQg2el190TTIv+666w5NqMRj4hgUZgHAfKqLU0ZJ2I3DYk+YRGyWE3HxNYrU45yUf6cYDIB5lBN15SKLSPD1mhOoduQZVChSvbI9xtVIngyrOh7XXTlfTUjlQpJZUj2GUfe/LvEWzzHsdkeJ3eJCxyuvvPKw39VdTBn7lrs1xP5Hoq1uGc8u1CU5x/GalAu2RulGNey+VP/9xAWjbTpwVDX59wkwz+o+96qFM6GuMHsUdUWzdftS/d2sxUejGjWGmGQMUvd6xSo9k9x+L8MeZ/U92KWcJ60u/RixTdzKcuFW/n9MjjFhXinYAqZedSKizbKAMZkUVyWUtxEBQa8r4m655ZYjApY777yzUTAQAUQUaEUCsfx8sb9RPT5KsJj3KQq1qhNkAMB8qVvab7GLkbpOvMXxRswWMVXdUgQAsJTERWLluYCYe+jVPby6lN6gzgpNkoXjVo1rZjEZWT2GcSRyq0ZZpmaU2C13tY+LB/uJ90l+r5QTbdNyoeGo76txvi+HfT2q/xZdpAAwmsjdVNV9Rlc/a8cxJ6Jga/Imeb7q3jvmqtqJhhpHHXXUwKW/c5F8Oc+al4WOGNO/C+bNsgQw5UYNUqvFWb2CqPh9tXPXMBNM0Y2rHMDnhOOoqhO0AMB8qos96pYOmkcRN0VyMDp7RNF7JP9MgAGw1FW7dudlEavqlkMcZVm4SZlEErRr8140E3HY5s2bi7motvNw8d6M7vWx9NNinqdR31fViygUSgHMvrr4ydKw0I28mlHc2uZd4/85UegV84XReAPmiQ5bwMyJycc2QXRcGXjw4MGB94tgvTr5Mswa3zGRFY8rF39FsrFXV6+mongMAJh/eWmZclwS8U+vJZabykXkebvxPKNuc5xi8iWSe70KtGJ/c1v0+D6Wvs4t0uNrnKN4PADMm3xFeTnJWLcsYnU5xLycYj/VopbcXWlc6opmqvs0i8XZ1eOax2KeeJ0ioRYizor3X3T9ystRlzts1YmkWvz9nnvuSYth1CXFq500FqOwsPp/gphrHGcR5iwWSwKMotfSa4uhyfMqFp4e1dcrYozFinFmXeRP4xbv74gr4xZxV8Ru+Xf93vt5FaZRc64wLRRsAVMvgubyFaJxhV4sUzjutpfVLljDXEWYxeRJuWArBxjDBv8xYarNJwAsHRH/lJOyMak4avI0lomuLi096rLN41RXrBXxWBSVLeYkKgBMg2rBVt2yiNXlRZoUZtfNNUx6/mEeip3iHJXnqkY9hmpntBDF6dMiYrFeF0/m5aujYLD6Hoz3bMSxMa81SXXv2VFfk2lYurNasLVY+wEwD2JMqs459OryM4ni8upYX/d5HmNt+blmKUaa9+7odZ03jcmjiTgn/g32+neYi7kid1vtjherEcX/dcwVMg8siQhMveqkTgzQF198cVG4FZM+g6qtm6oGzOvXr0/Dqk5i5SsPh9W2PSgAMNuq8U/EEXWt+9uoXkmaO3lNg9yBoSyuVMxt0pvsZ3R8AIB5Vb2CvLosYt1yiE3mEqqJplHjjSbWrVt32M+jzpkshnGft2o3pzArSzTFfkbsGnFbLKNYPTfVCyQnoS6ujYsVRtEksT5p1fdAXWEfAM3UjUe9OvRUi6Zz559h1T2+Gg+FxYjLxmXe52TGnfNjsDjncSFnzA9WL1SJ81/tLgyzSsEWMPUiaK4GqjEYR2LvyiuvLIq3Tj755OIW30d3huuuu64IwJtOZMT2qgFzbCPWQx7mFvtRNUrwNk1XVQIAk1fXEWPUZFd1om+aCsKrkywxIdN2/2ZpIhMA2spXoJeVx89hlkMM1eXVqoVgbcXcR8zX5FvdXEhd58xR4py4oK88J9NFgVD1vI1aXD9NSzSNoryMYtZVkVE1kVo9p23UvZ6jXNg5rOq/+TimUQoG4pjK/z4ttQUsFflzr6zfCit1nSFHiS/qYoS6wuy6+GLYcTQeG3mqcs6q7nO/Lt4Y5jnnfU5m3PFrznHmmzmt/mLFgLqLW2EeKNgCpl4EQVFBPWiiMa9tHIFNLEcYAXcOSAcFTnWBaq6QH/ZWNcoVBtp6AsDSUpeUHWUCpy5h2mSZpK5UY7FhislGScoBwCyoJinKicdhlkMMMddSHXdHLZ4q3+q2FXFONUlZ3f+mcoFYeT6mi4ve6jqADnve8jGU9er4MWnlixdjTm2YRNhiLQ9U/fdRt/RVUzfeeOPA7Xeh+u94lG4S8di48LX871PHLmApiLGg7nP9+uuv7/mYujmZUeYcqs8fuau6nE9dUdCwn/sxDuZli3OHr7rnjN9Vf79p06bU1lKYk4nXrWzY+DXccssth43Jde/ReRHvvfLFFRGPDKP6b1LhOfNCwRYwE2KyJ9qqx1V6bVvCRzAagVQEAr0mIroY2KtrXAMA9FM3eRiTOG3jlrrJybrk7GIaNpmW9ergAQDzpK54IxelDLMcYlZXCDZMkXhdV6JehWPVOCceG4mrthYzxokr/cuGPW91CbrFitPKFy/Ge2qYIrRqrNrVRYjxXqs+V8TObdUV0PVKrE9aXcHADTfcMNQ8Zvz7Kj9u2v4/ADAJMZbFiizV+YKIQwYVGFdjlRjjh41Vml5AF5/71fgiPvfbFtjWzQP1+8yv5tyiIUIbS2VOpq4D2jDvibpYY5ouqhy3eF+XY8wo7humaHyxYkyYNAVbQCvjKmwadjsxQfLggw8WxVt33nlnEazmJXMGtYuPQKAuOA91j4uuXvE847otxpV4AMDsivimOlHXL56pk6+kr5ucnCbVycE2EzdxbNENAgDmXa9lEauJoph/aNPlKLo5Ve8fhS5tEm85Rinrt9RQHEf1WCLuaVPwFInIarKryxgnzltdgVCb89brGBarS1U1WRgJ27YJ2GonkLYXXg4rXou65HqbOLHufRyvxWLGztUlJmMf2xaiRWwdc6hl0/b/AYBxirmQGGPrukXG53r1M7FOr1ilTSepKHyuPlfOZ/VSF1/Uzev0E2Nfm3mgus5FTTs+LaU5mThP1S5b8Z5oW3xUfX3iPVnd7rypxoPDdBSrxsyLsVw1TIKCLaCvahv5XAU9qmoAs27dutRGBDAxARlBZkxcRHFVFHJt3769uMXPN9100xETXLH/dZMadQVbcd94/LhuAABt1SXs8hWigzoeRIIqJiercVdMAk3bRFDd8o9NJrzyMda19h/lQoN4rNbqAEyjum5Y1cRh9er/JuqKQiLeaFJAFfepFpTXFc/UPWd1/I7tDErgxBgdia5qArRpsqvXHFBbsZ1e521QnJbnp+qOoUkSeVIiJivHnrGfbS4WqEtMD9MxYtil+iJpWo0ro+isSaK77n0c6goauxTPHXOcZfFvvumSlVHQGfetbnPeE8PA0pM7j+blfevG0/j8i9xRU3WxSowpTWOV6mdtkyLguhgqxxeDisXifvGZX73foGLwuqWY4/wNOs5+czLzqi7vGOegSaetfq/PNKu+tlu3bk1tVY8xzkGboq3qRRE6hTJPjkkAfdRdBbdx48aRJirqJvvGOfGRrzjNXSkiMC63cI3nrwaQ8X3sQ3nAHyboAAAYp4hRYjKxmjzKSz7HBFruNBrLLz/zzDOH2ovXJXDqEj7TIBJ55eVdcnIwYrhIOpfjtvhbJPFiYqccV8ZEakyclu8XEzr5irvYRq+Op9WYNz9/vw6pcS7nuWU9ANOpbsysFhsN0+E74omIEcodEnJyMHcTiIvt8pgczxnzQxFz1M3zxLg8aK4n/l4dv0McXxSixXHEOJ6fM/Zn06ZNxd+qx9wmAVuXUIzkWb8ClnhMXTIzX0xYTjiV47SYlypfpDjKMcRj6uaq6orNImnYK3Ea76F+r028JuUuUzm5GMca56AubqqLzcKgLiJZdV/jfRVxXL/9jPdG3bbz/pdj4dhe3PL+5AtUY9/jnPZ6H8drW+14m8X2exXmVQvO8vmp0ySmzN07ys8XP0dBQhxTxMuxnfK/lfj3WbdEVdtiBYBpkf+fXvf7Jo0G4vM/Vm1pU1iU51CqTQCGiVVCPH+TXFh87le7XMW2I2aK44jnrcYXMUbUjWVx30HF4HkpxupSiPk4y/FMr7Ezxsyl0GkrzlW8jvFeLL/G+fzlc1V+neM8RQfSuoK7OG/TXkSdlzTM8jKd/f4tVTvF5Xxt+T2W31/xtTr3F+I5431d1/FVp1DmykGAARYGyYPxcZFvCwPrwVEsBB+HbW8hcDk4adVjWJiYODhov0Y9zoWg7eDCJFFxi+/biHMyaH8BgKVj8+bNR8QHbW8LybViO00sTJYc9tiIk4ZRja/6bWdhErTvvkdsFuegGtfFLR4b4j79zkEv27dvr93uoBsALIZ+492wY3bWbzxucovxNOZB2og5k2HG4fK8UtMYJ4vYou3z9HuOhaTRSOetyTGMGgvmW8R5g8Rr2O81jn3Jt37xW8RYTcS8V9vj6PdeH0fsHK/psOeo7a2phUTnxN9nANOiOi8x7C3GrTxnMKxRY5V47DA5nlHjiyuuuKLxWBz3G3bszGNmm/GtbuxvqzoWD5PTazNvVfbggw9OPNbIqrF/k1iuyXZuv/32Ro8bJv7ote2rrrqq77+THF/2+/fW9LzBrLAkIjBQtbo7qsGHXRYxHlet8u93pV1cDRZXi+Vbk7aideo6hVVVr2aL/WzS+r9OVJfH1Q5x5UXc4nvL6gAAw4or82L552Gvuosr2+JK+nF2NR23uNKu1xVyEVvlGLQcU+UOZLnzwbBX2DVZtgkApkW/bjzDLIdYFmPq5s2bh4oZYn5nmHglOj/E44Z5zmEfO+6Oo9EZYNhYK+K0YY9/UuI17PU+yF1M8q1Ojj2bdjHJnfLHJcfOvbpjDXpsdM5YzKUpe4n3bZPudXWm8X0GMEn5//kxng0zHpSNEqvk+GiYcS7GomE+9+PYY8xo01Esz68ME1PlMXOpLIsYIucY52uYebrc7XIaY40641weOjpq9Zp/K8eYdfnUvBz5rJw3aErBFjBQ3WRftQVsU9HCtU3ryoMHDx42CTTJgTgC5mrQ0WYN5bJqYVkE9EspWAUAxi9PTMRkY0wIDZosyS3tYxIo2oe3iUXyMjG9fm6q3KK/yXYi1svH10954rU86Rnfx/HG1+rxDjpfca7i/NY9to5kFwCLJeYY6sah+N0wyyHWbSfG2Dwu9hNjZh5/RykOb/ucESvE87Vd2ijrFzP0es5B94tttTmGtnHauOaVmsZ1bV6TMErsGeJxEd81uegyDDqOnKxuGjvHMcbzR1K9yb+jccWCbbeT3/vxugw6V/k1iXMwzGsCsJjazEPE51uOg/JYtH379mKOYVyffYsRH4X43I+xqenn/ihFauVj7LfP8TxxrqvPU35Mkzmr6nO3NY7Xtu28VVle3rtp4Va8J/K8XpsCvupxDjtHV93O6tWrGz0uF5jFMTY95/22XZ77a/K6x33y+3ral4+EYRwVbbYSwACxHnO121QMjBFcNBXFT9WCqybbOPnkkw+rpo4JhqjobioKvaI7V1kE63WBRawhHd2wymKf23RcqDvOCKibTjiF2N9yYVueRAQAKIvOU7mw/ZlnnikmRCLGibijTewxjSL+i+OLW/nY6orsAYDJyWNyxBtbt24tfheJoog1YkyeRBHIYjznuFVjmZCPYRbjtLrXZNZiz7z/mzZtKn6O/Y/3U9PCvWkUx5OPa97+PwAwzXrFKjGuxOfvpMaVXp/7k5grqY6bXRzfrMvd4cvvifz6OGf1qu/p4LyxlCjYAhqJgfLiiy8+og1lriDvV0wUAUoUMVULvnJV9qAgsq4AqmnRVux3FJuVi58GFYnF3++4447DfhdXCQxq+xnnJvY19q0sHlf93SAKtgAAAAAAAABgPinYAhqLtYV7LYWYr0aLr1H5HNXjUcAURVpRGV0n2tY3bdUfxWLV7URh1VVXXVVbzR/FTlF0FYVS5SKzuN+gtcbj/lHkVX2+fIzxnOXHx/02btxYnJ9qQVtex7quAjzOTTyuTnW/+7UGXb9+vWIuAAAAAAAAAJgRCraAVqIo6brrrjuiMKmNKF666aabWq01XNcpq6xczBT7Vrd/8bxRPNWkHXivoq02oogqitJ6teusW2ZyGG2XpgQAAAAAAAAAFs+yBNBCFAcN6lDVTxQxxePbFGuFeL5+j4tCrnyrK9bKna6aFGuF3Inr+uuvT23lgrRenbUAAAAAAAAAgKVLwRbQWhRPbd68ufGShlG0FIVaUcAUt2GLvWI70UkqnjsKt5oUQ8XzxmOi+KppsVbZDTfccOj5Bu13/D0KvOL+1157bRpkXMVcsQQlAAAAAAAAADAbLIkIjEUs7RedrTZt2lT8vHr16qIgKYqkopBpUp2mYsnC3FnrmWeeKX4XBUzxnPHc437e6vPl44zCsGEL0QAAAAAAAACApUPBFgAAAAAAAAAAQEcsiQgAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAADQEQVbAAAAAAAAAAAAHVGwBQAAAAAAAAAA0BEFWwAAAAAAAAAAAB1RsAUAAAAAAAAAANARBVsAAAAAAAAAAAAdUbAFAAAAAAAAAP9/u3YsAAAAADDI33oWu4ojAJgIWwAAAAAAAAAAABNhCwAAAAAAAAAAYCJsAQAAAAAAAAAATIQtAAAAAAAAAACAibAFAAAAAAAAAAAwEbYAAAAAAAAAAAAmwhYAAAAAAAAAAMBE2AIAAAAAAAAAAJgIWwAAAAAAAAAAABNhCwAAAAAAAAAAYCJsAQAAAAAAAAAATIQtAAAAAAAAAACAibAFAAAAAAAAAAAwEbYAAAAAAAAAAAAmwhYAAAAAAAAAAMBE2AIAAAAAAAAAAJgIWwAAAAAAAAAAABNhCwAAAAAAAAAAYCJsAQAAAAAAAAAATIQtAAAAAAAAAACAibAFAAAAAAAAAAAwEbYAAAAAAAAAAAAmwhYAAAAAAAAAAMBE2AIAAAAAAAAAAJgIWwAAAAAAAAAAABNhCwAAAAAAAAAAYCJsAQAAAAAAAAAATIQtAAAAAAAAAACAibAFAAAAAAAAAAAwEbYAAAAAAAAAAAAmwhYAAAAAAAAAAMBE2AIAAAAAAAAAAJgIWwAAAAAAAAAAABNhCwAAAAAAAAAAYCJsAQAAAAAAAAAATAJ7TPFvdOQOhAAAAABJRU5ErkJggg==)" + ] + }, + { + "cell_type": "markdown", + "id": "f6ab2d5d", + "metadata": { + "id": "f6ab2d5d" + }, + "source": [ + "Here is a summary of the steps involved.\n", + "\n", + "Initial phase:\n", + "- **Step 0**: Ingest the documents – get documents, chunk, embed, and index.\n", + "\n", + "For each user-chatbot interaction:\n", + "- **Step 1**: Get the user message\n", + "- **Step 2**: Call the Chat endpoint in query-generation mode\n", + "- If at least one query is generated\n", + " - **Step 3**: Retrieve and rerank relevant documents\n", + " - **Step 4**: Call the Chat endpoint in document mode to generate a grounded response with citations\n", + "- If no query is generated\n", + " - **Step 4**: Call the Chat endpoint in normal mode to generate a response" + ] + }, + { + "cell_type": "markdown", + "id": "TWyo_5WoNUM-", + "metadata": { + "id": "TWyo_5WoNUM-" + }, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5pLAhQmTOKiV", + "metadata": { + "id": "5pLAhQmTOKiV" + }, + "outputs": [], + "source": [ + "! pip install cohere hnswlib unstructured -q" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3a03a57", + "metadata": { + "id": "f3a03a57" + }, + "outputs": [], + "source": [ + "import cohere\n", + "import uuid\n", + "import hnswlib\n", + "from typing import List, Dict\n", + "from unstructured.partition.html import partition_html\n", + "from unstructured.chunking.title import chunk_by_title\n", + "\n", + "co = cohere.Client(\"COHERE_API_KEY\") # Get your API key here: https://dashboard.cohere.com/api-keys" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "Dx1cncziCWBB", + "metadata": { + "cellView": "form", + "id": "Dx1cncziCWBB" + }, + "outputs": [], + "source": [ + "#@title Enable text wrapping in Google Colab\n", + "\n", + "from IPython.display import HTML, display\n", + "\n", + "def set_css():\n", + " display(HTML('''\n", + " \n", + " '''))\n", + "get_ipython().events.register('pre_run_cell', set_css)" + ] + }, + { + "cell_type": "markdown", + "id": "2f7e7d1c", + "metadata": { + "id": "2f7e7d1c" + }, + "source": [ + "# Create a vector store for ingestion and retrieval\n", + "\n", + "First, we define the list of documents we want to ingest and make available for retrieval. As an example, we'll use the contents from the first module of Cohere's *LLM University: What are Large Language Models?*." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dca4a88", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 + }, + "id": "3dca4a88", + "outputId": "b05da1ee-0456-4387-c232-a43e0ffed54c" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "raw_documents = [\n", + " {\n", + " \"title\": \"Text Embeddings\",\n", + " \"url\": \"https://docs.cohere.com/docs/text-embeddings\"},\n", + " {\n", + " \"title\": \"Similarity Between Words and Sentences\",\n", + " \"url\": \"https://docs.cohere.com/docs/similarity-between-words-and-sentences\"},\n", + " {\n", + " \"title\": \"The Attention Mechanism\",\n", + " \"url\": \"https://docs.cohere.com/docs/the-attention-mechanism\"},\n", + " {\n", + " \"title\": \"Transformer Models\",\n", + " \"url\": \"https://docs.cohere.com/docs/transformer-models\"}\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "5e2a8968", + "metadata": { + "id": "5e2a8968" + }, + "source": [ + "Usually the number of documents for practical applications is vast, and so we'll need to be able to search documents efficiently. This involves breaking the documents into chunks, generating embeddings, and indexing the embeddings, as shown in the image below. \n", + "\n", + "We implement this in the `Vectorstore` class below, which takes the `raw_documents` list as input. Three methods are immediately called when creating an object of the `Vectorstore` class:\n", + "\n", + "\n", + "`load_and_chunk()` \n", + "This method uses the `partition_html()` method from the `unstructured` library to load the documents from URL and break them into smaller chunks. Each chunk is turned into a dictionary object with three fields:\n", + "- `title` - the web page’s title,\n", + "- `text` - the textual content of the chunk, and\n", + "- `url` - the web page’s URL. \n", + " \n", + " \n", + "`embed()` \n", + "This method uses Cohere's `embed-english-v3.0` model to generate embeddings of the chunked documents. Since our documents will be used for retrieval, we set `input_type=\"search_document\"`. We send the documents to the Embed endpoint in batches, because the endpoint has a limit of 96 documents per call.\n", + "\n", + "`index()` \n", + "This method uses the `hsnwlib` package to index the document chunk embeddings. This will ensure efficient similarity search during retrieval. Note that `hnswlib` uses a vector library, and we have chosen it for its simplicity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c33412c", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 + }, + "id": "7c33412c", + "outputId": "cf04f8ed-8000-4433-f976-2d37747f21e7" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "class Vectorstore:\n", + " \"\"\"\n", + " A class representing a collection of documents indexed into a vectorstore.\n", + "\n", + " Parameters:\n", + " raw_documents (list): A list of dictionaries representing the sources of the raw documents. Each dictionary should have 'title' and 'url' keys.\n", + "\n", + " Attributes:\n", + " raw_documents (list): A list of dictionaries representing the raw documents.\n", + " docs (list): A list of dictionaries representing the chunked documents, with 'title', 'text', and 'url' keys.\n", + " docs_embs (list): A list of the associated embeddings for the document chunks.\n", + " docs_len (int): The number of document chunks in the collection.\n", + " idx (hnswlib.Index): The index used for document retrieval.\n", + "\n", + " Methods:\n", + " load_and_chunk(): Loads the data from the sources and partitions the HTML content into chunks.\n", + " embed(): Embeds the document chunks using the Cohere API.\n", + " index(): Indexes the document chunks for efficient retrieval.\n", + " retrieve(): Retrieves document chunks based on the given query.\n", + " \"\"\"\n", + "\n", + " def __init__(self, raw_documents: List[Dict[str, str]]):\n", + " self.raw_documents = raw_documents\n", + " self.docs = []\n", + " self.docs_embs = []\n", + " self.retrieve_top_k = 10\n", + " self.rerank_top_k = 3\n", + " self.load_and_chunk()\n", + " self.embed()\n", + " self.index()\n", + "\n", + "\n", + " def load_and_chunk(self) -> None:\n", + " \"\"\"\n", + " Loads the text from the sources and chunks the HTML content.\n", + " \"\"\"\n", + " print(\"Loading documents...\")\n", + "\n", + " for raw_document in self.raw_documents:\n", + " elements = partition_html(url=raw_document[\"url\"])\n", + " chunks = chunk_by_title(elements)\n", + " for chunk in chunks:\n", + " self.docs.append(\n", + " {\n", + " \"title\": raw_document[\"title\"],\n", + " \"text\": str(chunk),\n", + " \"url\": raw_document[\"url\"],\n", + " }\n", + " )\n", + "\n", + " def embed(self) -> None:\n", + " \"\"\"\n", + " Embeds the document chunks using the Cohere API.\n", + " \"\"\"\n", + " print(\"Embedding document chunks...\")\n", + "\n", + " batch_size = 90\n", + " self.docs_len = len(self.docs)\n", + " for i in range(0, self.docs_len, batch_size):\n", + " batch = self.docs[i : min(i + batch_size, self.docs_len)]\n", + " texts = [item[\"text\"] for item in batch]\n", + " docs_embs_batch = co.embed(\n", + " texts=texts, model=\"embed-english-v3.0\", input_type=\"search_document\"\n", + " ).embeddings\n", + " self.docs_embs.extend(docs_embs_batch)\n", + "\n", + " def index(self) -> None:\n", + " \"\"\"\n", + " Indexes the document chunks for efficient retrieval.\n", + " \"\"\"\n", + " print(\"Indexing document chunks...\")\n", + "\n", + " self.idx = hnswlib.Index(space=\"ip\", dim=1024)\n", + " self.idx.init_index(max_elements=self.docs_len, ef_construction=512, M=64)\n", + " self.idx.add_items(self.docs_embs, list(range(len(self.docs_embs))))\n", + "\n", + " print(f\"Indexing complete with {self.idx.get_current_count()} document chunks.\")\n", + "\n", + " def retrieve(self, query: str) -> List[Dict[str, str]]:\n", + " \"\"\"\n", + " Retrieves document chunks based on the given query.\n", + "\n", + " Parameters:\n", + " query (str): The query to retrieve document chunks for.\n", + "\n", + " Returns:\n", + " List[Dict[str, str]]: A list of dictionaries representing the retrieved document chunks, with 'title', 'text', and 'url' keys.\n", + " \"\"\"\n", + "\n", + " # Dense retrieval\n", + " query_emb = co.embed(\n", + " texts=[query], model=\"embed-english-v3.0\", input_type=\"search_query\"\n", + " ).embeddings\n", + "\n", + " doc_ids = self.idx.knn_query(query_emb, k=self.retrieve_top_k)[0][0]\n", + "\n", + " # Reranking\n", + " docs_to_rerank = [self.docs[doc_id][\"text\"] for doc_id in doc_ids]\n", + "\n", + " rerank_results = co.rerank(\n", + " query=query,\n", + " documents=docs_to_rerank,\n", + " top_n=self.rerank_top_k,\n", + " model=\"rerank-english-v2.0\",\n", + " )\n", + "\n", + " doc_ids_reranked = [doc_ids[result.index] for result in rerank_results.results]\n", + "\n", + " docs_retrieved = []\n", + " for doc_id in doc_ids_reranked:\n", + " docs_retrieved.append(\n", + " {\n", + " \"title\": self.docs[doc_id][\"title\"],\n", + " \"text\": self.docs[doc_id][\"text\"],\n", + " \"url\": self.docs[doc_id][\"url\"],\n", + " }\n", + " )\n", + "\n", + " return docs_retrieved" + ] + }, + { + "cell_type": "markdown", + "id": "e1bf5d85", + "metadata": { + "id": "e1bf5d85" + }, + "source": [ + "In the code cell below, we initialize an instance of the `Vectorstore` class and pass in the `raw_documents` list as input." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4643e630", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 178 + }, + "id": "4643e630", + "outputId": "fe01fcb6-3574-4322-d8d0-57d37aad397d" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading documents...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[nltk_data] Downloading package punkt to /root/nltk_data...\n", + "[nltk_data] Unzipping tokenizers/punkt.zip.\n", + "[nltk_data] Downloading package averaged_perceptron_tagger to\n", + "[nltk_data] /root/nltk_data...\n", + "[nltk_data] Unzipping taggers/averaged_perceptron_tagger.zip.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Embedding document chunks...\n", + "Indexing document chunks...\n", + "Indexing complete with 136 document chunks.\n" + ] + } + ], + "source": [ + "# Create an instance of the Vectorstore class with the given sources\n", + "vectorstore = Vectorstore(raw_documents)" + ] + }, + { + "cell_type": "markdown", + "id": "61928287", + "metadata": { + "id": "61928287" + }, + "source": [ + "The `Vectorstore` class also has a `retrieve()` method, which we'll use to retrieve relevant document chunks given a query (as in Step 3 in the diagram shared at the beginning of this notebook). This method has two components: (1) dense retrieval, and (2) reranking.\n", + "\n", + "### Dense retrieval\n", + "\n", + "First, we embed the query using the same `embed-english-v3.0` model we used to embed the document chunks, but this time we set `input_type=\"search_query\"`.\n", + "\n", + "Search is performed by the `knn_query()` method from the `hnswlib` library. Given a query, it returns the document chunks most similar to the query. We can define the number of document chunks to return using the attribute `self.retrieve_top_k=10`.\n", + "\n", + "### Reranking\n", + "\n", + "After semantic search, we implement a reranking step. While our semantic search component is already highly capable of retrieving relevant sources, the [Rerank endpoint](https://cohere.com/rerank) provides an additional boost to the quality of the search results, especially for complex and domain-specific queries. It takes the search results and sorts them according to their relevance to the query.\n", + "\n", + "We call the Rerank endpoint with the `co.rerank()` method and define the number of top reranked document chunks to retrieve using the attribute `self.rerank_top_k=3`. The model we use is `rerank-english-v2.0`. \n", + "\n", + "This method returns the top retrieved document chunks `chunks_retrieved` so that they can be passed to the chatbot.\n", + "\n", + "In the code cell below, we check the document chunks that are retrieved for the query `\"multi-head attention definition\"`." + ] + }, + { + "cell_type": "markdown", + "id": "OwozNf_uPEyX", + "metadata": { + "id": "OwozNf_uPEyX" + }, + "source": [ + "## Test Retrieval" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82617b91", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 267 + }, + "id": "82617b91", + "outputId": "7f1f2bc8-8ed9-4190-bd6b-7af2d9dc1980" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[{'title': 'Transformer Models',\n", + " 'text': 'The attention step used in transformer models is actually much more powerful, and it’s called multi-head attention. In multi-head attention, several different embeddings are used to modify the vectors and add context to them. Multi-head attention has helped language models reach much higher levels of efficacy when processing and generating text.',\n", + " 'url': 'https://docs.cohere.com/docs/transformer-models'},\n", + " {'title': 'The Attention Mechanism',\n", + " 'text': \"What you learned in this chapter is simple self-attention. However, we can do much better than that. There is a method called multi-head attention, in which one doesn't only consider one embedding, but several different ones. These are all obtained from the original by transforming it in different ways. Multi-head attention has been very successful at the task of adding context to text. If you'd like to learn more about the self and multi-head attention, you can check out the following two\",\n", + " 'url': 'https://docs.cohere.com/docs/the-attention-mechanism'},\n", + " {'title': 'Transformer Models',\n", + " 'text': 'Attention helps give context to each word, based on the other words in the sentence (or text).',\n", + " 'url': 'https://docs.cohere.com/docs/transformer-models'}]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vectorstore.retrieve(\"multi-head attention definition\")" + ] + }, + { + "cell_type": "markdown", + "id": "e69fbca9", + "metadata": { + "id": "e69fbca9" + }, + "source": [ + "# Create a chatbot\n", + "\n", + "Next, we implement a class to handle the interaction between the user and the chatbot. It takes an instance of the `Vectorstore` class as input.\n", + "\n", + "The `run()` method will be used to run the chatbot application. It begins with the logic for getting the user message, along with a way for the user to end the conversation. \n", + "\n", + "Based on the user message, the chatbot needs to decide if it needs to consult external information before responding. If so, the chatbot determines an optimal set of search queries to use for retrieval. When we call `co.chat()` with `search_queries_only=True`, the Chat endpoint handles this for us automatically.\n", + "\n", + "The generated queries can be accessed from the `search_queries` field of the object that is returned. Then, what happens next depends on how many queries are returned.\n", + "- If queries are returned, we call the `retrieve()` method of the Vectorstore object for the retrieval step. The retrieved document chunks are then passed to the Chat endpoint by adding a `documents` parameter when we call `co.chat()` again.\n", + "- Otherwise, if no queries are returned, we call the Chat endpoint another time, passing the user message and without needing to add any documents to the call.\n", + "\n", + "In either case, we also pass the `conversation_id` parameter, which retains the interactions between the user and the chatbot in the same conversation thread. We also enable the `stream` parameter so we can stream the chatbot response.\n", + "\n", + "We then print the chatbot's response. In the case that the external information was used to generate a response, we also display citations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2c15a1f", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 + }, + "id": "d2c15a1f", + "outputId": "8daa9159-338c-45ec-e9ed-830aedcdf0d8" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "class Chatbot:\n", + " def __init__(self, vectorstore: Vectorstore):\n", + " \"\"\"\n", + " Initializes an instance of the Chatbot class.\n", + "\n", + " Parameters:\n", + " vectorstore (Vectorstore): An instance of the Vectorstore class.\n", + "\n", + " \"\"\"\n", + " self.vectorstore = vectorstore\n", + " self.conversation_id = str(uuid.uuid4())\n", + "\n", + " def run(self):\n", + " \"\"\"\n", + " Runs the chatbot application.\n", + "\n", + " \"\"\"\n", + " while True:\n", + " # Get the user message\n", + " message = input(\"User: \")\n", + "\n", + " # Typing \"quit\" ends the conversation\n", + " if message.lower() == \"quit\":\n", + " print(\"Ending chat.\")\n", + " break\n", + " # else: # Uncomment for Google Colab to avoid printing the same thing twice\n", + " # print(f\"User: {message}\") # Uncomment for Google Colab to avoid printing the same thing twice\n", + "\n", + " # Generate search queries (if any)\n", + " response = co.chat(message=message,\n", + " model=\"command-r\",\n", + " search_queries_only=True)\n", + "\n", + " # If there are search queries, retrieve document chunks and respond\n", + " if response.search_queries:\n", + " print(\"Retrieving information...\", end=\"\")\n", + "\n", + " # Retrieve document chunks for each query\n", + " documents = []\n", + " for query in response.search_queries:\n", + " documents.extend(self.vectorstore.retrieve(query.text))\n", + "\n", + " # Use document chunks to respond\n", + " response = co.chat_stream(\n", + " message=message,\n", + " model=\"command-r\",\n", + " documents=documents,\n", + " conversation_id=self.conversation_id,\n", + " )\n", + "\n", + " # If there is no search query, directly respond\n", + " else:\n", + " response = co.chat_stream(\n", + " message=message,\n", + " model=\"command-r\",\n", + " conversation_id=self.conversation_id,\n", + " )\n", + "\n", + " # Print the chatbot response, citations, and documents\n", + " print(\"\\nChatbot:\")\n", + " citations = []\n", + " cited_documents = []\n", + "\n", + " # Display response\n", + " for event in response:\n", + " if event.event_type == \"text-generation\":\n", + " print(event.text, end=\"\")\n", + " elif event.event_type == \"citation-generation\":\n", + " citations.extend(event.citations)\n", + " elif event.event_type == \"search-results\":\n", + " cited_documents = event.documents\n", + "\n", + " # Display citations and source documents\n", + " if citations:\n", + " print(\"\\n\\nCITATIONS:\")\n", + " for citation in citations:\n", + " print(citation)\n", + "\n", + " print(\"\\nDOCUMENTS:\")\n", + " for document in cited_documents:\n", + " print(document)\n", + "\n", + " print(f\"\\n{'-'*100}\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "F0X9FZqwOwQ6", + "metadata": { + "id": "F0X9FZqwOwQ6" + }, + "source": [ + "# Run the chatbot" + ] + }, + { + "cell_type": "markdown", + "id": "3cb442f7", + "metadata": { + "id": "3cb442f7" + }, + "source": [ + "We can now run the chatbot. For this, we create the instance of `Chatbot` and run the chatbot by invoking the `run()` method.\n", + "\n", + "The format of each citation is:\n", + "- `start`: The starting point of a span where one or more documents are referenced\n", + "- `end`: The ending point of a span where one or more documents are referenced\n", + "- `text`: The text representing this span\n", + "- `document_ids`: The IDs of the documents being referenced (`doc_0` being the ID of the first document passed to the `documents` creating parameter in the endpoint call, and so on)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42d3f345", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "42d3f345", + "outputId": "8b935c8b-b1d4-4913-bdf8-73ba503402b8" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "User: Hello, I have a question\n", + "\n", + "Chatbot:\n", + "Hello! What's your question? I'm here to help you in any way I can.\n", + "----------------------------------------------------------------------------------------------------\n", + "\n", + "User: What’s the difference between word and sentence embeddings\n", + "Retrieving information...\n", + "Chatbot:\n", + "Word embeddings associate words with lists of numbers. Similar words are assigned numbers that are mathematically close while dissimilar words are assigned numbers that are far apart. \n", + "\n", + "Sentence embeddings do the same thing as word embeddings, but for sentences. Each sentence is associated with a vector of numbers in a coherent way. This means that similar sentences are assigned similar vectors and dissimilar sentences are assigned different vectors.\n", + "\n", + "CITATIONS:\n", + "start=0 end=15 text='Word embeddings' document_ids=['doc_0']\n", + "start=16 end=54 text='associate words with lists of numbers.' document_ids=['doc_0']\n", + "start=55 end=68 text='Similar words' document_ids=['doc_0']\n", + "start=82 end=119 text='numbers that are mathematically close' document_ids=['doc_0']\n", + "start=126 end=142 text='dissimilar words' document_ids=['doc_0']\n", + "start=156 end=183 text='numbers that are far apart.' document_ids=['doc_0']\n", + "start=186 end=205 text='Sentence embeddings' document_ids=['doc_0', 'doc_2']\n", + "start=213 end=242 text='same thing as word embeddings' document_ids=['doc_0', 'doc_2']\n", + "start=263 end=276 text='Each sentence' document_ids=['doc_0', 'doc_2']\n", + "start=298 end=315 text='vector of numbers' document_ids=['doc_0', 'doc_2']\n", + "start=321 end=329 text='coherent' document_ids=['doc_2']\n", + "start=351 end=368 text='similar sentences' document_ids=['doc_0', 'doc_2']\n", + "start=382 end=397 text='similar vectors' document_ids=['doc_0', 'doc_2']\n", + "start=402 end=422 text='dissimilar sentences' document_ids=['doc_0', 'doc_2']\n", + "start=436 end=454 text='different vectors.' document_ids=['doc_0', 'doc_2']\n", + "\n", + "DOCUMENTS:\n", + "{'id': 'doc_0', 'text': 'In the previous chapters, you learned about word and sentence embeddings and similarity between words and sentences. In short, a word embedding is a way to associate words with lists of numbers (vectors) in such a way that similar words are associated with numbers that are close by, and dissimilar words with numbers that are far away from each other. A sentence embedding does the same thing, but associating a vector to every sentence. Similarity is a way to measure how similar two words (or', 'title': 'The Attention Mechanism', 'url': 'https://docs.cohere.com/docs/the-attention-mechanism'}\n", + "{'id': 'doc_1', 'text': 'Sentence embeddings\\n\\nSo word embeddings seem to be pretty useful, but in reality, human language is much more complicated than simply a bunch of words put together. Human language has structure, sentences, etc. How would one be able to represent, for instance, a sentence? Well, here’s an idea. How about the sums of scores of all the words? For example, say we have a word embedding that assigns the following scores to these words:\\n\\nNo: [1,0,0,0]\\n\\nI: [0,2,0,0]\\n\\nAm: [-1,0,1,0]\\n\\nGood: [0,0,1,3]', 'title': 'Text Embeddings', 'url': 'https://docs.cohere.com/docs/text-embeddings'}\n", + "{'id': 'doc_2', 'text': 'This is where sentence embeddings come into play. A sentence embedding is just like a word embedding, except it associates every sentence with a vector full of numbers, in a coherent way. By coherent, I mean that it satisfies similar properties as a word embedding. For instance, similar sentences are assigned to similar vectors, different sentences are assigned to different vectors, and most importantly, each of the coordinates of the vector identifies some (whether clear or obscure) property of', 'title': 'Text Embeddings', 'url': 'https://docs.cohere.com/docs/text-embeddings'}\n", + "\n", + "----------------------------------------------------------------------------------------------------\n", + "\n", + "User: And what are their similarities\n", + "Retrieving information...\n", + "Chatbot:\n", + "The similarity between word and sentence embeddings lies in the fact that they both measure similarity between items. For example, if two sentences are very similar, their corresponding vectors will also be similar. This is best illustrated with an example: \n", + "\n", + "The similarities between the following sentences can be computed using sentence embeddings:\n", + "1. Who was the 16th president of the US and fought in the American Civil War?\n", + "2. The American Civil War saw the 16th President, Abraham Lincoln, attempt to preserve the Union.\n", + "3. Lincoln was the 16th president of the United States.\n", + "\n", + "The similarity between sentences 1 and 2 is 6738.2859, which is very high. On the other hand, the similarities between sentences 1 and 3, and 2 and 3, are much lower at -122.2267 and -3.4946 respectively.\n", + "\n", + "CITATIONS:\n", + "start=84 end=102 text='measure similarity' document_ids=['doc_0', 'doc_2']\n", + "start=131 end=215 text='if two sentences are very similar, their corresponding vectors will also be similar.' document_ids=['doc_0']\n", + "start=589 end=638 text='similarity between sentences 1 and 2 is 6738.2859' document_ids=['doc_1']\n", + "start=683 end=734 text='similarities between sentences 1 and 3, and 2 and 3' document_ids=['doc_1']\n", + "start=754 end=775 text='-122.2267 and -3.4946' document_ids=['doc_1']\n", + "\n", + "DOCUMENTS:\n", + "{'id': 'doc_0', 'text': 'Notice that these sentences are all very similar. In particular, the three highlighted sentences pretty much have the same meaning. If you look at their corresponding vectors, these are also really similar. That is exactly what an embedding should do.', 'title': 'Text Embeddings', 'url': 'https://docs.cohere.com/docs/text-embeddings'}\n", + "{'id': 'doc_1', 'text': 'And the results are:\\n\\nThe similarity between sentences 1 and 2: 6738.2858668486715\\n\\nThe similarity between sentences 1 and 3: -122.22666955510499\\n\\nThe similarity between sentences 2 and 3: -3.494608113647928\\n\\nThese results certainly confirm our predictions. The similarity between sentences 1 and 2 is 6738, which is high. The similarities between sentences 1 and 3, and 2 and 3, are -122 and -3.5 (dot products are allowed to be negative too!), which are much lower.', 'title': 'Similarity Between Words and Sentences', 'url': 'https://docs.cohere.com/docs/similarity-between-words-and-sentences'}\n", + "{'id': 'doc_2', 'text': 'The similarity between each sentence and itself is 1 (the diagonal in the plot), which is consistent with our expectations. Furthermore, a sentence and itself represent the same point in space, which gives an angle of 0 with the origin, so it makes sense that the similarity is the cosine of 0, which is 1!\\n\\nConclusion', 'title': 'Similarity Between Words and Sentences', 'url': 'https://docs.cohere.com/docs/similarity-between-words-and-sentences'}\n", + "\n", + "----------------------------------------------------------------------------------------------------\n", + "\n", + "User: What do you know about 5G networks\n", + "Retrieving information...\n", + "Chatbot:\n", + "Unfortunately, I could not find any information about 5G networks in the available documentation. However, I can tell you about the 4G networks which have preceded 5G. 4G networks enable a high-speed connection and were designed to support a wide range of functions on mobile devices, including video streaming and high-quality music streaming. They also support a wider coverage area and better spectral efficiency, allowing more devices to connect simultaneously.\n", + "----------------------------------------------------------------------------------------------------\n", + "\n", + "User: quit\n", + "Ending chat.\n" + ] + } + ], + "source": [ + "# Create an instance of the Chatbot class\n", + "chatbot = Chatbot(vectorstore)\n", + "\n", + "# Run the chatbot\n", + "chatbot.run()" + ] + }, + { + "cell_type": "markdown", + "id": "9e69aa7c", + "metadata": { + "id": "9e69aa7c" + }, + "source": [ + "In the conversation above, notice a few observations that reflect the different components of what we built:\n", + "\n", + "- **Direct response**: For user messages that don’t require retrieval, such as \"Hello, I have a question\", the chatbot responds directly without requiring retrieval.\n", + "- **Citation generation**: For responses that do require retrieval (\"What’s the difference between word and sentence embeddings\"), the endpoint returns the response together with the citations.\n", + "- **State management**: The endpoint maintains the state of the conversation via the `conversation_id` parameter, for example, by being able to correctly respond to a vague user message of \"And what are their similarities\".\n", + "- **Response synthesis**: The model can decide if none of the retrieved documents provide the necessary information required to answer a user message. For example, when asked the question \"What do you know about 5G networks\", the chatbot goes on and retrieves external information from the index. However, it doesn’t use any of the information in its response as none of them is relevant to the question." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "-JBWZVz9ObcV", + "metadata": { + "id": "-JBWZVz9ObcV" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/.ipynb_checkpoints/Vanilla_Multi_Step_Tool_Use-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/Vanilla_Multi_Step_Tool_Use-checkpoint.ipynb new file mode 100644 index 00000000..550e7d87 --- /dev/null +++ b/notebooks/.ipynb_checkpoints/Vanilla_Multi_Step_Tool_Use-checkpoint.ipynb @@ -0,0 +1,979 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Multi-Step Tool Use\n", + "\n", + "Tool use allows developers to connect Cohere's models to external tools like search engines, APIs, functions, databases, etc.\n", + "\n", + "Multi-step tool use is an extension of this basic idea, and allows the model to call more than one tool in a sequence of steps, using the results from one tool call in a subsequent step. This process allows the language model to reason, perform dynamic actions, and quickly adapt on the basis of information coming from external sources.\n", + "\n", + "The recommended way to achieve [multi-step tool use with Cohere](https://docs.cohere.com/docs/multi-step-tool-use) is by leveraging the [Langchain framework](https://python.langchain.com/docs/integrations/providers/cohere#react-agent) in Python." + ], + "metadata": { + "id": "aH1iAdZiURXh" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Install Dependencies" + ], + "metadata": { + "id": "PVT6Sl3msjNe" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0m31LaFDjCIY", + "outputId": "7177e241-a864-47ed-cf0a-5fc9fa70a7ec" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m812.8/812.8 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[32m194.1/194.1 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m9.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m276.8/276.8 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m87.5/87.5 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m145.9/145.9 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m21.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.8/144.8 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "! pip install --quiet langchain langchain_cohere langchain_experimental" + ] + }, + { + "cell_type": "code", + "source": [ + "# LLM\n", + "import os\n", + "os.environ['COHERE_API_KEY'] = " + ], + "metadata": { + "id": "K0GELKJVnadW" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Define tools\n", + "\n", + "Your agent will be equipped with the following tools. The model can pick between\n", + "\n", + "- doing a search on the web\n", + "- and/or retrieving data from a vector store\n", + "- and/or using a python interpreter\n", + "- and/or directly answering [ this tool comes out of the box! ]\n", + "\n", + "Plus the model can self-reflect." + ], + "metadata": { + "id": "6l1pDbAmsptW" + } + }, + { + "cell_type": "markdown", + "source": [ + "#### Web search\n", + "You can easily equip your agent with web search!" + ], + "metadata": { + "id": "_9riBTvIVnaN" + } + }, + { + "cell_type": "code", + "source": [ + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "\n", + "os.environ[\"TAVILY_API_KEY\"] = # you can create an API key for free on Tavily's website\n", + "\n", + "internet_search = TavilySearchResults()\n", + "internet_search.name = \"internet_search\"\n", + "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", + "\n", + "\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class TavilySearchInput(BaseModel):\n", + " query: str = Field(description=\"Query to search the internet with\")\n", + "internet_search.args_schema = TavilySearchInput" + ], + "metadata": { + "id": "6wMNTOGNVvwA" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Vector store\n", + "You can easily equip your agent with a vector store!" + ], + "metadata": { + "id": "pax1SemzX6Kg" + } + }, + { + "cell_type": "code", + "source": [ + "!pip --quiet install faiss-cpu tiktoken" + ], + "metadata": { + "id": "cc4d4pRFndYu", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "6478fd6b-5618-4d0b-8928-44f78e3ca7e6" + }, + "execution_count": 4, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m27.0/27.0 MB\u001b[0m \u001b[31m41.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m58.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import FAISS\n", + "from langchain_cohere import CohereEmbeddings\n", + "\n", + "# Set embeddings\n", + "embd = CohereEmbeddings()\n", + "\n", + "# Docs to index\n", + "urls = [\n", + " \"https://paulgraham.com/best.html\",\n", + "]\n", + "\n", + "# Load\n", + "docs = [WebBaseLoader(url).load() for url in urls]\n", + "docs_list = [item for sublist in docs for item in sublist]\n", + "\n", + "# Split\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=512, chunk_overlap=0\n", + ")\n", + "doc_splits = text_splitter.split_documents(docs_list)\n", + "\n", + "# Add to vectorstore\n", + "vectorstore = FAISS.from_documents(\n", + " documents=doc_splits,\n", + " embedding=embd,\n", + ")\n", + "\n", + "vectorstore_retriever = vectorstore.as_retriever()\n" + ], + "metadata": { + "id": "eqcorKP4YEH6" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from langchain.tools.retriever import create_retriever_tool\n", + "\n", + "vectorstore_search = create_retriever_tool(\n", + " retriever=vectorstore_retriever,\n", + " name=\"vectorstore_search\",\n", + " description=\"Retrieve relevant info from a vectorstore that contains information from Paul Graham about how to write good essays.\"\n", + ")" + ], + "metadata": { + "id": "eQFNJ-38abRd" + }, + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Python interpreter tool\n", + "You can easily equip your agent with a python interpreter!" + ], + "metadata": { + "id": "aB90i9W5YqWi" + } + }, + { + "cell_type": "code", + "source": [ + "from langchain.agents import Tool\n", + "from langchain_experimental.utilities import PythonREPL\n", + "\n", + "python_repl = PythonREPL()\n", + "python_tool = Tool(\n", + " name=\"python_repl\",\n", + " description=\"Executes python code and returns the result. The code runs in a static sandbox without interactive mode, so print output or save output to a file.\",\n", + " func=python_repl.run,\n", + ")\n", + "python_tool.name = \"python_interpreter\"\n", + "\n", + "# from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class ToolInput(BaseModel):\n", + " code: str = Field(description=\"Python code to execute.\")\n", + "python_tool.args_schema = ToolInput" + ], + "metadata": { + "id": "AN-4FqXKYEFw" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "8vj868w_YED_" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Transform any Python function in a Tool\n", + "You can easily equip your agent with any Python function!" + ], + "metadata": { + "id": "2SDCaoypexGL" + } + }, + { + "cell_type": "code", + "source": [ + "from langchain_core.tools import tool\n", + "import random\n", + "\n", + "@tool\n", + "def random_operation_tool(a: int, b: int):\n", + " \"\"\"Calculates a random operation between the inputs.\"\"\"\n", + " coin_toss = random.uniform(0, 1)\n", + " if coin_toss > 0.5:\n", + " return {'output': a*b}\n", + " else:\n", + " return {'output': a+b}\n", + "\n", + "random_operation_tool.name = \"random_operation\" # use python case\n", + "random_operation_tool.description = \"Calculates a random operation between the inputs.\"\n", + "\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class random_operation_inputs(BaseModel):\n", + " a: int = Field(description=\"First input\")\n", + " b: int = Field(description=\"Second input\")\n", + "random_operation_tool.args_schema = random_operation_inputs" + ], + "metadata": { + "id": "DYUJT2xKewny" + }, + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Create ReAct Agent\n", + "\n", + "The model can smartly pick the right tool(s) for the user query, call them in any sequence, analyze the results and self-reflect. \n", + "Once the model considers it has enough information to answer the user question, it generates the final answer." + ], + "metadata": { + "id": "hcspRBsRY2ED" + } + }, + { + "cell_type": "code", + "source": [ + "from langchain.agents import AgentExecutor\n", + "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_cohere.chat_models import ChatCohere\n", + "\n", + "# LLM\n", + "llm = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"\n", + "You are an expert who answers the user's question with the most relevant datasource. You are equipped with an internet search tool and a special vectorstore of information about how to write good essays.\n", + "You also have a 'random_operation_tool' tool, you must use it to compute the random operation between two numbers.\n", + "\"\"\"\n", + "\n", + "\n", + "# Prompt template\n", + "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", + "\n", + "# Create the ReAct agent\n", + "agent = create_cohere_react_agent(\n", + " llm=llm,\n", + " tools=[internet_search, vectorstore_search, python_tool, random_operation_tool],\n", + " prompt=prompt,\n", + ")\n", + "\n", + "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool, random_operation_tool], verbose=True)" + ], + "metadata": { + "id": "CY83aAprYECO" + }, + "execution_count": 13, + "outputs": [] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "RK0NaqngYD_J" + }, + "execution_count": 13, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Ask a standalone question to the ReAct agent\n", + "A question that requires using a predefined tool from Langchain" + ], + "metadata": { + "id": "mzTQcVXSaBe7" + } + }, + { + "cell_type": "code", + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"I want to write an essay about the Roman Empire. Any tips for writing an essay? Any fun facts?\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the model smartly looks in the vector db, and then online" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "rR2hWVp-aEsU", + "outputId": "fcf9b8b3-7027-4679-c06d-ef166f016892" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for tips on writing an essay and fun facts about the Roman Empire.\n", + "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'tips for writing an essay'}}\n", + "\u001b[0m\u001b[33;1m\u001b[1;3mbe? I should have asked how do you write essays well? Though\n", + "these seem only phrasing apart, their answers diverge. The answer\n", + "to the first question, as we've seen, isn't really about essay\n", + "writing. The second question forces it to be.Writing essays, at its best, is a way of discovering ideas. How do\n", + "you do that well? How do you discover by writing?An essay should ordinarily start with what I'm going to call a\n", + "question, though I mean this in a very general sense: it doesn't\n", + "have to be a question grammatically, just something that acts like\n", + "one in the sense that it spurs some response.How do you get this initial question? It probably won't work to\n", + "choose some important-sounding topic at random and go at it.\n", + "Professional traders won't even trade unless they have what they\n", + "call an edge — a convincing story about why in some class of\n", + "trades they'll win more than they lose. Similarly, you shouldn't\n", + "attack a topic unless you have a way in — some new insight about\n", + "it or way of approaching it.You don't need to have a complete thesis; you just need some kind\n", + "of gap you can explore. In fact, merely having questions about\n", + "something other people take for granted can be edge enough.If you come across a question that's sufficiently puzzling, it could\n", + "be worth exploring even if it doesn't seem very momentous. Many an\n", + "important discovery has been made by pulling on a thread that seemed\n", + "insignificant at first. How can they all be finches? \n", + "[2]Once you've got a question, then what? You start thinking out loud\n", + "about it. Not literally out loud, but you commit to a specific\n", + "string of words in response, as you would if you were talking. This\n", + "initial response is usually mistaken or incomplete. Writing converts\n", + "your ideas from vague to bad. But that's a step forward, because\n", + "once you can see the brokenness, you can fix it.Perhaps beginning writers are alarmed at the thought of starting\n", + "with something mistaken or incomplete, but you shouldn't be, because\n", + "this is why essay writing works. Forcing yourself to commit to some\n", + "specific string of words gives you a starting point, and if it's\n", + "wrong, you'll see that when you reread it. At least half of essay\n", + "writing is rereading what you've written and asking is this correct\n", + "\n", + "didn't have edge with any of them. To start writing an essay, you\n", + "need a topic plus some initial insight about it, and you can't\n", + "generate those systematically. If only. \n", + "[9]You can probably cause yourself to have more of them, though. The\n", + "quality of the ideas that come out of your head depends on what goes\n", + "in, and you can improve that in two dimensions, breadth and depth.You can't learn everything, so getting breadth implies learning\n", + "about topics that are very different from one another. When I tell\n", + "people about my book-buying trips to Hay and they ask what I buy\n", + "books about, I usually feel a bit sheepish answering, because the\n", + "topics seem like a laundry list of unrelated subjects. But perhaps\n", + "that's actually optimal in this business.You can also get ideas by talking to people, by doing and building\n", + "things, and by going places and seeing things. I don't think it's\n", + "important to talk to new people so much as the sort of people who\n", + "make you have new ideas. I get more new ideas after talking for an\n", + "afternoon with Robert Morris than from talking to 20 new smart\n", + "people. I know because that's what a block of office hours at Y\n", + "Combinator consists of.While breadth comes from reading and talking and seeing, depth comes\n", + "from doing. The way to really learn about some domain is to have\n", + "to solve problems in it. Though this could take the form of writing,\n", + "I suspect that to be a good essayist you also have to do, or have\n", + "done, some other kind of work. That may not be true for most other\n", + "fields, but essay writing is different. You could spend half your\n", + "time working on something else and be net ahead, so long as it was\n", + "hard.I'm not proposing that as a recipe so much as an encouragement to\n", + "those already doing it. If you've spent all your life so far working\n", + "on other things, you're already halfway there. Though of course to\n", + "be good at writing you have to like it, and if you like writing\n", + "you'd probably have spent at least some time doing it.Everything I've said about initial questions applies also to the\n", + "questions you encounter in writing the essay. They're the same\n", + "thing; every subtree of an essay is usually a shorter essay, just\n", + "as every subtree of a Calder mobile is a smaller mobile. So any\n", + "\n", + "You don't have to get an answer right the first time, but there's\n", + "no excuse for not getting it right eventually, because you can keep\n", + "rewriting till you do. And this is not just a theoretical possibility.\n", + "It's a pretty accurate description of the way I work. I'm rewriting\n", + "as we speak.But although I wish I could say that writing great essays depends mostly\n", + "on effort, in the limit case it's inspiration that makes the\n", + "difference. In the limit case, the questions are the harder thing\n", + "to get. That pool has no bottom.How to get more questions? That is the most important question of\n", + "all.Notes[1]\n", + "There might be some resistance to this conclusion on the\n", + "grounds that some of these discoveries could only be understood by\n", + "a small number of readers. But you get into all sorts of difficulties\n", + "if you want to disqualify essays on this account. How do you decide\n", + "where the cutoff should be? If a virus kills off everyone except a \n", + "handful of people sequestered at Los Alamos,\n", + "could an essay that had been disqualified now be eligible? Etc.Darwin's 1844 essay was derived from an earlier version written in 1839.\n", + "Extracts from it were published in 1858.[2]\n", + "When you find yourself very curious about an apparently minor\n", + "question, that's an exciting sign. Evolution has designed you to\n", + "pay attention to things that matter. So when you're very curious\n", + "about something random, that could mean you've unconsciously noticed\n", + "it's less random than it seems.[3]\n", + "Corollary: If you're not intellectually honest, your writing\n", + "won't just be biased, but also boring, because you'll miss all the\n", + "ideas you'd have discovered if you pushed for the truth.[4]\n", + "Sometimes this process begins before you start writing.\n", + "Sometimes you've already figured out the first few things you want\n", + "to say. Schoolchildren are often taught they should decide everything\n", + "they want to say, and write this down as an outline before they\n", + "start writing the essay itself. Maybe that's a good way to get them\n", + "started — or not, I don't know — but it's antithetical to the\n", + "spirit of essay writing. The more detailed your outline, the less\n", + "your ideas can benefit from the sort of discovery that essays are for.[5]\n", + "The problem with this type of \"greedy\" algorithm is that you\n", + "\n", + "technique that gets you good initial questions also gets you good\n", + "whole essays.At some point the cycle of question and response reaches what feels\n", + "like a natural end. Which is a little suspicious; shouldn't every\n", + "answer suggest more questions? I think what happens is that you\n", + "start to feel sated. Once you've covered enough interesting ground,\n", + "you start to lose your appetite for new questions. Which is just\n", + "as well, because the reader is probably feeling sated too. And it's\n", + "not lazy to stop asking questions, because you could instead be\n", + "asking the initial question of a new essay.That's the ultimate source of drag on the connectedness of ideas:\n", + "the discoveries you make along the way. If you discover enough\n", + "starting from question A, you'll never make it to question B. Though\n", + "if you keep writing essays you'll gradually fix this problem by\n", + "burning off such discoveries. So bizarrely enough, writing lots of\n", + "essays makes it as if the space of ideas were more highly connected.When a subtree comes to an end, you can do one of two things. You\n", + "can either stop, or pull the Cubist trick of laying separate subtrees\n", + "end to end by returning to a question you skipped earlier. Usually\n", + "it requires some sleight of hand to make the essay flow continuously\n", + "at this point, but not this time. This time I actually need an\n", + "example of the phenomenon. For example, we discovered earlier that\n", + "the best possible essay wouldn't usually be timeless in the way the\n", + "best painting would. This seems surprising enough to be\n", + "worth investigating further.There are two senses in which an essay can be timeless: to be about\n", + "a matter of permanent importance, and always to have the same effect\n", + "on readers. With art these two senses blend together. Art that\n", + "looked beautiful to the ancient Greeks still looks beautiful to us.\n", + "But with essays the two senses diverge, because essays\n", + "teach, and you can't teach people something they already know.\n", + "Natural selection is certainly a matter of permanent importance,\n", + "but an essay explaining it couldn't have the same effect on us that\n", + "it would have had on Darwin's contemporaries, precisely because his\n", + "ideas were so successful that everyone already knows about them.\n", + "[10]I imagined when I started writing this that the best possible essay\n", + "would be timeless in the stricter, evergreen sense: that it would\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the roman empire'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.natgeokids.com/uk/discover/history/romans/10-facts-about-the-ancient-romans/', 'content': 'i love this website\\nBIG BOBBY\\nbooby\\nI love shell my bae;)\\ni like bobby fishes ;0\\nI like turtles\\nOmg soy cool\\ngreeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatttttttttttttttttttttttt\\nbest fact ever\\nthis artical is cool\\nHANDY\\nrubbish did not help what so ever\\nha\\nRocking\\nTHIS IS THE BEST\\nproper rad in it cool\\nthis is cool\\nawesomeness\\nawsome\\nawsome\\nthank you captain\\nit is a lot of help\\ni like this\\nwebsite it helps me on my projects and isabel likes munier\\nmark uses this for research\\nlot of help\\nthis is awsome\\nTHE BEST BOOBOO\\nCool webpage helped me get 4 housepoints\\n This helped me A LOT on a school project\\ncool wow awesomoe\\nCOOL WEBSITE LOL\\nthis helped me with a school project :)\\nthat was awesome\\ncool\\nthat helped me out for my research test\\nReally its very cool really COOL\\nLIKE COOL best website so far its nice\\nI love it\\nnice facts\\nIt help with my history\\n i mean u made animaljam a awesome nice safe place for kids and this site to have kids a safe website to get facts for reports and stuff\\nLots of Love ,\\nRose\\npretty good website if u ask me\\nbut definently not gonna use it on a daily basis\\nIll try it again another time\\ngood\\nCool webcite\\nterrible\\nquite impressive\\nAwesome website it real helps\\nits good\\nthis is a great website! You really a lot with my project!:)\\nthis has helleped\\nme get\\nmy progect\\ndone\\nthank you\\nsoooooooooooooooooo\\nmuchchchchchch\\nthis helleped me\\nsooooooooo much with my progect thank you\\nvery good website\\nthank us very much your nice one today!!\\n'}, {'url': 'https://ohfact.com/roman-empire-facts/', 'content': 'Learn about the ancient Roman Civilization, its history, culture, army, architecture, food and more from this list of 27 facts. Discover how the Romans started, conquered, lived, died and influenced the world with their legends, myths and facts.'}, {'url': 'https://factnight.com/fun-facts-about-the-roman-empire/', 'content': 'The Roman Empire was one of the most influential and significant civilizations in world history. At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people. From its legendary beginnings and remarkable achievements to its eventual decline and fall, the Roman Empire is a fascinating topic full of little-known facts and intriguing trivia.'}, {'url': 'https://www.historyhit.com/facts-about-ancient-rome-and-the-romans/', 'content': 'The Enduring Legacy of C.S. Lewis\\nMargaret J. Winkler: A Forgotten Pioneer in Disney’s Success\\n10 Facts About Harper Lee\\nAntarctica Expedition Cruise\\nUncover Pompeii\\nSophie Hay and Tristan Hughes\\nRediscovering Richard III with Matt Lewis\\nOrder the History Hit Miscellany\\nHistory Hit Holidays\\nGift Subscriptions\\n100 Facts About Ancient Rome and the Romans\\nRome wasn’t built in a day, as the cliché reminds us. The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire\\nBarbarian factions, tribes and war leaders were now a factor in the power struggles at the top of Roman politics and one of the once-strong boundaries of the Empire had proved to be permeable.\\n Related Articles\\n10 Facts About Saint Andrew\\nThe Rise of Pompey the Great, the ‘Roman Alexander’\\nWatch and Listen\\nCleopatra\\nSex in Ancient Rome\\nRelated Locations\\nBaelo Claudia\\nMausoleum of Cecilia Metella\\nColin Ricketts\\n30 July 2021\\n By the fourth century BC, the story was accepted by Romans who were proud of their warrior founder\\nThe story was included in the first history of the city, by the Greek writer Diocles of Peparethus, and the twins and their wolf step-mother were depicted on Rome’s first coins.\\n The History Hit Miscellany of Facts, Figures and Fascinating Finds\\nA History of England: Part One\\nDragons: Myth & Reality\\nA Tudor Wonder - Hardwick Hall\\nThe Battle of Shrewsbury\\nEurope’s 1848 Revolutions\\nThe Boston Tea Party\\nHow Did 3 People Seemingly Escape From Alcatraz?\\n'}, {'url': 'https://www.countryfaq.com/facts-about-the-roman-empire/', 'content': 'Facts about the Roman Empire. Explore some of the interesting, fun, cool facts bout the Roman Empire: 1. The Magnificent Roman Empire. The Roman Empire, a colossal entity of unparalleled grandeur, occupies an indomitable position within the annals of human history, a name that resonates resoundingly across the eons.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,3,4,5\n", + "Cited Documents: 0,3,4,5\n", + "Answer: Here are some tips for writing an essay:\n", + "- Start with a question that spurs some response.\n", + "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", + "- You don't need a complete thesis, just a gap to explore.\n", + "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", + "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", + "- You can get breadth by reading and talking about a wide range of topics.\n", + "- You can get depth by doing and having to solve problems.\n", + "- You can also get ideas by talking to people who make you have new ideas.\n", + "\n", + "Here are some fun facts about the Roman Empire:\n", + "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", + "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", + "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\n", + "Grounded answer: Here are some tips for writing an essay:\n", + "- Start with a question that spurs some response.\n", + "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", + "- You don't need a complete thesis, just a gap to explore.\n", + "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", + "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", + "- You can get breadth by reading and talking about a wide range of topics.\n", + "- You can get depth by doing and having to solve problems.\n", + "- You can also get ideas by talking to people who make you have new ideas.\n", + "\n", + "Here are some fun facts about the Roman Empire:\n", + "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", + "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", + "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"Here are some tips for writing an essay:\\n- Start with a question that spurs some response.\\n- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\\n- You don't need a complete thesis, just a gap to explore.\\n- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\\n- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\\n- You can get breadth by reading and talking about a wide range of topics.\\n- You can get depth by doing and having to solve problems.\\n- You can also get ideas by talking to people who make you have new ideas.\\n\\nHere are some fun facts about the Roman Empire:\\n- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\\n- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\\n- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "DIP1YkXCg7rQ" + }, + "execution_count": 14, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "A question that requires the large language model to use a custom tool." + ], + "metadata": { + "id": "FhwS3VHvg3_l" + } + }, + { + "cell_type": "code", + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"Calculate the result of the random operation of 10 and 20. Then find a few fun facts about that number, as well as its prime factors.\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the model uses a sequence of tools" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 645 + }, + "id": "79Dw6Zhrg3xI", + "outputId": "a41c6de9-cb64-4cff-a58b-e9481d438f6c" + }, + "execution_count": 22, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "First, I will calculate the result of the random operation between 10 and 20. Then, I will search for fun facts about that number and its prime factors.\n", + "{'tool_name': 'random_operation_tool', 'parameters': {'a': 10, 'b': 20}}\n", + "\u001b[0mrandom_operation_tool is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3m\n", + "I received an error message when trying to use the random_operation_tool. I will now try using the python_interpreter tool to calculate the random operation between 10 and 20.\n", + "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import random\\n\\n# Define the two numbers\\na = 10\\nb = 20\\n\\n# Calculate the random operation\\nresult = random.choice(['+', '-', '*', '/'])\\n\\n# Perform the operation\\nif result == '+':\\n answer = a + b\\nelif result == '-':\\n answer = a - b\\nelif result == '*':\\n answer = a * b\\nelif result == '/':\\n answer = a / b\\n\\nprint(f'The result of the random operation is {answer:.0f}')\"}}\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mThe result of the random operation is 200\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "The result of the random operation is 200. Now I will search for fun facts about the number 200 and its prime factors.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the number 200'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.express.co.uk/life-style/top10facts/690340/Top-10-facts-number-200', 'content': \"Top 10 facts about the number 200 TODAY is the 200th day of 2016, so to celebrate let's have some facts about the number 200. By WILLIAM HARTSTON. 00:01, Mon, Jul 18, 2016.\"}, {'url': 'https://en.wikipedia.org/wiki/200_(number)', 'content': \"The number appears in the Padovan sequence, preceded by 86, 114, 151 (it is the sum of the first two of these). The sum of Euler's totient function φ(x) over the first twenty-five integers is 200. 200 is the smallest base 10 unprimeable number - it cannot be turned into a prime number by changing just one of its digits to any other digit.\"}, {'url': 'https://www.archimedes-lab.org/numbers/Num70_200.html', 'content': \"With 189 pages filled with an incredible variety of fun facts on numbers (and their peculiar properties), both mathematical and cultural, as well as tantalizing problems and anecdotes, there is much to learn for everyone. ... The number 200, according to Bullinger's study of biblical literature, signifies 'insufficiency'. The word 200 (ducenti) ...\"}, {'url': 'https://owlcation.com/misc/Over-200-Odd-Facts-Did-You-Know-Them', 'content': \"Over 200 odd facts about science, sports, history and more that you and your friends probably don't already know! ... Strange and Interesting Facts. ... Average number of people airborne over the U.S. at any given hour: 61,000. Portion of land in the U.S. owned by the government: 1/3. Ninety percent of New York City cabbies are recently arrived ...\"}, {'url': 'https://numbermatics.com/n/200/', 'content': 'Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. Your guide to the number 200, an even composite number composed of two distinct primes. Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. ... Number 200 - Facts about the integer. Retrieved 2 April ...'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'prime factors of 200'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.cuemath.com/numbers/factors-of-200/', 'content': 'Therefore, the factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, and 200. Which means the number 200 is an even composite number.'}, {'url': 'https://byjus.com/maths/factors-of-200/', 'content': \"The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200. Visit BYJU'S to learn the pair factors and the prime factors of 200 with complete\\xa0...\"}, {'url': 'https://byjus.com/us/math/factors-of-200/', 'content': 'The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200 because all these numbers divide the number 200 evenly.'}, {'url': 'https://homework.study.com/explanation/what-is-the-prime-factorization-of-200-using-exponents.html', 'content': 'The prime factorization of 200 using exponents is 2 3 ∗ 5 2 . First, we need to find the prime factorization of 200. 200 = 2 ∗ 100. 200 = 2 ∗ 2 ∗ 50.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,3,4,6,7,8,9,10\n", + "Cited Documents: 1,3,4,6,7,8,9,10\n", + "Answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", + "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", + "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", + "- The number 200 is an even composite number composed of two distinct primes.\n", + "\n", + "The prime factors of 200 are 2 and 5.\n", + "Grounded answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", + "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", + "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", + "- The number 200 is an even composite number composed of two distinct primes.\n", + "\n", + "The prime factors of 200 are 2 and 5.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"The result of the random operation is **200**. Here are some fun facts about the number 200:\\n- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\\n- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\\n- The number 200 is an even composite number composed of two distinct primes.\\n\\nThe prime factors of 200 are 2 and 5.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "V8LcAh8vaEqR" + }, + "execution_count": 15, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "A question that requires the large language model to directly answer." + ], + "metadata": { + "id": "n9nV_jiaAaD1" + } + }, + { + "cell_type": "code", + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"Hey how are you?\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the modle can directly answer!" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 250 + }, + "id": "tRf6V3gJAZkO", + "outputId": "aec1acdb-876c-48e9-a1f5-e3ba8a0f19ed" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will respond to the user's greeting.\n", + "{'tool_name': 'directly_answer', 'parameters': {}}\n", + "\u001b[0mdirectly_answer is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", + "Cited Documents: None\n", + "Answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\n", + "Grounded answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "hnLkln_ckYXJ" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Ask a more complex question to the ReAct agent\n", + "A question that requires using multipe tools, in sequence" + ], + "metadata": { + "id": "3h-icRL2_5iu" + } + }, + { + "cell_type": "code", + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"In what year was the company that was founded as Sound of Music went public? What was its stock price in 2000 and 2010.\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 377 + }, + "id": "Q4IyoXXRaEoL", + "outputId": "0e935f68-8b7c-4d9a-b8f1-1be57b7c9a1f" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for the company that was founded as Sound of Music. Then, I will search for the year it went public. Finally, I will search for its stock price in 2000 and 2010.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'company founded as Sound of Music'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.mprnews.org/story/2012/05/15/best-buy-richard-schulze-legacy', 'content': 'Amazon is taking a piece of everyone\\'s business,\"\\nSome analysts have questioned the extent to which Schulze\\'s strong hand over the company has held it back in the face of digital competition. \"\\nSchulze hit on the \"Best Buy\" strategy when a twister ripped open a store and the company held a huge sale with low prices and lots of promotion. And Richard Schulz was able to outthink and outmaneuver the competition to put up Best Buy as the definitive place in the brick-and-mortar world to buy electronic equipment,\" Spector said.\\n Best Buy\\'s Richard Schulze: Stereo seller to retail giant\\nShare\\nIn 1966, Best Buy was a stereo specialty retailer called Sound of Music, founded by Richard Schulze in St. Paul.\\n Former CEO Anderson said it is possible that Schulze\\'s goals for the company were out of touch with the digital age, and that Schulze may have stuck around too long.\\n'}, {'url': 'https://corporate.bestbuy.com/tag/sound-of-music/', 'content': 'As we celebrate Best Buy’s 50th anniversary, we sat down with founder and Chairman Emeritus Dick Schulze and current Chairman and CEO Hubert Joly to talk about how we got to where we are today and get a glimpse into where we’re going next.\\n Sound of Music\\n22 Aug: Best Buy at 50: A Q&A with Founder Dick Schulze and CEO Hubert Joly\\nTechnology has changed a lot over the past half century, and so has Best Buy.\\n 14 Jun: 35 Years Ago Today, A Tornado Transformed Best Buy\\nOn the afternoon of June 14, 1981, a tornado slammed into the Minneapolis suburbs, mere miles from where the Best Buy corporate headquarters now stands.\\n Little did he know that it would become Best Buy, a nearly $40 billion company that now sells everything from TVs and laptops to drones and virtual-reality headsets.\\n It was the most significant tornado to hit the Minneapolis-St. Paul area in 20 years — and its wake would change the path of our company.\\n'}, {'url': 'https://historydraft.com/story/best-buy/timeline/841', 'content': \"Best Buy announced the shutdown of the Future Shop chain in Canada\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.\\n Best Buy Company, Inc\\nIn 1983, with seven stores and $10 million in annual sales, Sound of Music was renamed Best Buy Company, Inc.\\nBest Buy debuted on the New York Stock Exchange\\nBest Buy was taken public in 1985, and two years later it debuted on the New York Stock Exchange.\\n The company closed all of its Best Buy-branded stores in China\\nThe company closed all of its Best Buy-branded stores in China by February 2011, when it merged Best Buy China's operations with Jiangsu Five Star, which had become a wholly-owned subsidiary of Best Buy in 2009.\\n Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores\\nIn July 2008, Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores, making the company the second-largest musical-instrument distributor in the US.\\n Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content\\nIn January 2004, Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content.\\n\"}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I have found that Best Buy was founded as Sound of Music. Now, I will search for the year it went public and its stock price in 2000 and 2010.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy went public'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.zippia.com/best-buy-careers-1455/history/', 'content': 'Meantime, Best Buy was taken public in 1985, raising $8 million through an IPO, and two years later gained a listing on the New York Stock Exchange (NYSE). ... Best Buy may also be known as or be related to Best Buy, Best Buy Co Inc, Best Buy Co., Inc., Sound of Music (1966-1983) Best Buy Co. Superstores (1983-1984) Best Buy Superstores ...'}, {'url': 'https://atouchofbusiness.com/companies/best-buy/', 'content': 'Public Listing and IPO: Best Buy went public in 1985 and listed on the NYSE in 1987. Conceptual Changes: The late 1980s and 1990s brought new store formats and growth, with revenues surpassing $1 billion. Overcoming Market Challenges. Supplier Relations: Mid-1990s challenges led to a merchandising revamp.'}, {'url': 'https://www.encyclopedia.com/social-sciences-and-law/economics-business-and-labor/businesses-and-occupations/best-buy-co-inc', 'content': 'Best Buy grew rapidly with $28.5 million in sales in 1984—compared to $9.9 million in 1983. In 1985, with 9 stores, Best Buy became a public company. By 1987, Best Buy had 24 stores and sales of $240 million, but it was beginning to feel the crunch as other rapidly expanding consumer electronics retailers pushed their way into the market.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy stock price in 2000 and 2010'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://finance.yahoo.com/quote/BBY/history/', 'content': 'Discover historical prices for BBY stock on Yahoo Finance. View daily, weekly or monthly format back to when Best Buy Co., Inc. stock was issued.'}, {'url': 'https://www.macrotrends.net/stocks/charts/BBY/best-buy/stock-price-history', 'content': 'Best Buy - 39 Year Stock Price History | BBY. Prices ... 2010, 25.1877, 25.7674, 31.2441, 20.2713, 22.3228 ... 2000, 16.0083, 15.2882, 22.8658, 5.9318, 7.8595, -\\xa0...'}, {'url': 'https://investors.bestbuy.com/investor-relations/stock-info/quote-and-chart/', 'content': 'Price 79.30. Change -0.88. Volume 666,622.'}, {'url': 'https://companiesmarketcap.com/best-buy/stock-price-history/', 'content': 'Stock price history for Best Buy (BBY). Highest end of day price: $138.00 USD on 2021-11-22. Lowest end of day price: $0.14 USD on 1985-05-02\\xa0...'}, {'url': 'https://www.netcials.com/stock-price-chart-history-nyse/BBY-Best-Buy-Co-Inc/', 'content': '1 Best Buy Co Inc (BBY) 20 Years Stock Chart History ; 2000, 16.24 (17.6%), 23.199 (29.07%) ; 2001, 14.80 (-8.87%), 20.1319 (-13.22%) ; 2002, 14.59 (-1.42%)\\xa0...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4,5,6,7,11,13,14\n", + "Cited Documents: 0,1,2,3,4,5,6,7,11,14\n", + "Answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\n", + "Grounded answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "L1BsKueTaEmg" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Have a multi-turn conversation with the ReAct agent\n", + "The chat history enables you to have multi-turn conversations with the ReAct agent." + ], + "metadata": { + "id": "53FDSFzQBFyf" + } + }, + { + "cell_type": "code", + "source": [ + "# Step 1: Construct the chat history as a list of LangChain Messages, ending with the last user message\n", + "from langchain_core.messages import HumanMessage, AIMessage\n", + "\n", + "chat_history = [\n", + " HumanMessage(content=\"I'm considering switching to Oracle for my CRM.\"),\n", + " AIMessage(content=\"That sounds like a good idea! How can I help you?\"),\n", + " HumanMessage(content=\"Recap me all the info you can find about their offering.\"),\n", + "]\n", + "\n", + "prompt = ChatPromptTemplate.from_messages(chat_history)" + ], + "metadata": { + "id": "1iYyAExsaEk9" + }, + "execution_count": 28, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Step 2: When you make the agent, specify the chat_history as the prompt, e.g.\n", + "# Create the ReAct agent\n", + "agent = create_cohere_react_agent(\n", + " llm=llm,\n", + " tools=[internet_search, vectorstore_search, python_tool],\n", + " prompt=prompt,\n", + ")\n", + "\n", + "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool], verbose=True)" + ], + "metadata": { + "id": "fyv_1LedaEi7" + }, + "execution_count": 29, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Step 3: When you invoke the agent_executor there's no need to pass anything else into invoke\n", + "response = agent_executor.invoke({\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']" + ], + "metadata": { + "id": "-ZCFj-m5nqFw", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + }, + "outputId": "3d71931e-1644-49b9-903c-4ff117787868" + }, + "execution_count": 30, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for 'Oracle CRM offering' and relay the information I find to the user.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Oracle CRM offering'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://docs.oracle.com/en/applications/siebel/', 'content': 'Siebel CRM delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations. With solutions tailored to more than 20 industries, Siebel CRM delivers comprehensive on-premise CRM solutions that are tailored industry solutions with role-based customer intelligence and pre-built integration.'}, {'url': 'https://www.softwareadvice.com/resources/breaking-down-oracle-crm/', 'content': \"Oracle's Marketing Cloud provides a comprehensive set of tools that cover a range of digital marketing needs. This includes tools for cross-channel marketing, i.e., marketing automation for both B2B and B2C marketers, as well as data management, content marketing and social media marketing. Cross-Channel Marketing.\"}, {'url': 'https://www.trustradius.com/products/oracle-crm-on-demand/reviews?qs=pros-and-cons', 'content': \"What is Oracle CRM On Demand?The basis of this offering is the Market2Lead product that Oracle acquired in 2010. It has now been fully integrated with Oracle's On Demand CRM product and is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI.\"}, {'url': 'https://www.oracle.com/cx/siebel/', 'content': 'In addition to standard CRM functionality, this industry solution includes asset, premises, and contracts management; work orders; oil well management and oil field service; B2C and B2B web portals; and credit and fraud management capabilities.\\nDesigned for pharmaceutical sales, Siebel CRM Life Sciences provides personalized content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction.\\n Marketing, sales, and customer service applications are fully integrated and designed to manage the complex interactions and relationships between brand owners, their partners (including brokers and distributors), their customers, and the end consumer.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n Provide world-class citizen services while delivering comprehensive, cost-efficient case management and policy management, including social services, justice and public safety, constituent services/311, self-service citizen portals, tax and revenue, and licensing and permitting.\\n'}, {'url': 'https://www.suretysystems.com/insights/oracle-customer-relationship-management-a-complete-overview/', 'content': 'Effective CRM systems offer the following features for enterprise users: Simple, easy-to-use interface; ... Oracle CRM simplifies customer relationship management by enhancing customer interactions and improving customer satisfaction and sales growth. Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM ...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4\n", + "Cited Documents: 0,1,2,3,4\n", + "Answer: Oracle's CRM offering includes the following:\n", + "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", + "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", + "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", + "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", + "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\n", + "Grounded answer: Oracle's CRM offering includes the following:\n", + "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", + "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", + "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", + "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", + "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"Oracle's CRM offering includes the following:\\n- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\\n- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\\n- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\\n- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\\n- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "8Zh01M4hWw3L" + }, + "execution_count": 30, + "outputs": [] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "0qEPY6xj_qwr" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/notebooks/.ipynb_checkpoints/Vanilla_RAG-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/Vanilla_RAG-checkpoint.ipynb new file mode 100644 index 00000000..2f85039c --- /dev/null +++ b/notebooks/.ipynb_checkpoints/Vanilla_RAG-checkpoint.ipynb @@ -0,0 +1,743 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "mz33G3t6gbOl" + }, + "source": [ + "# RAG\n", + "\n", + "Retrieval-Augmented Generation (RAG) is a technique that combines the strengths of pre-trained language models with the ability to retrieve information from a large corpus of documents. RAG **enables the language model to produce more informed, accurate, and contextually relevant answers** than by relying on its pre-trained knowledge alone.\n", + "\n", + "At Cohere, all RAG calls come with... **precise citations**! 🎉\n", + "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", + "These citations make it easy to check where the model’s generated response claims are coming from and they help users gain visibility into the model reasoning. \n", + "\n", + "RAG consists of 3 steps:\n", + "- Step 1: Indexing and given a user query, retrieve the relevant chunks from the index\n", + "- Step 2: Optionally, rerank the retrieved chunks\n", + "- Step 3: Generate the model final answer with **precise citations**, given the retrieved and reranked chunks\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nSB0pnt0gbOo" + }, + "source": [ + "## Step 0 - Imports & Getting some data\n", + "\n", + "In this example, we'll use a recent piece of text, that wasn't in the training data: the Wikipedia page of the movie \"Dune 2\". \n", + "\n", + "In practice, you would typically do RAG on much longer text, that doesn't fit in the context window of the model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "H787BXXYvD0a", + "outputId": "04ef5e04-7760-4d40-deeb-663536b38f20" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m33.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "# we'll use Cohere to cover all building blocks of RAG\n", + "# TODO: upgrade to \"cohere>5\"\n", + "%pip install \"cohere<5\" --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rACbepFGgbOo" + }, + "outputs": [], + "source": [ + "import cohere\n", + "API_KEY = \"...\" # fill in your Cohere API key here\n", + "co = cohere.Client(API_KEY)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QdvbqfFrgbOq", + "outputId": "3882c95c-46bf-4dcc-99a2-453b3c2fc7c4" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Building wheel for wikipedia (setup.py) ... \u001b[?25l\u001b[?25hdone\n" + ] + } + ], + "source": [ + "# we'll get some wikipedia data\n", + "!pip install wikipedia --quiet\n", + "import wikipedia" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xP-bWt9XgbOq", + "outputId": "72276fb2-0d6b-415d-af74-452a013ae84b" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The text has roughly 5323 words.\n" + ] + } + ], + "source": [ + "# let's get the wikipedia article about Dune Part Two\n", + "article = wikipedia.page('Dune Part Two')\n", + "text = article.content\n", + "print(f\"The text has roughly {len(text.split())} words.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1aJ7hKGgbOr" + }, + "source": [ + "## Step 1 - Indexing and given a user query, retrieve the relevant chunks from the index\n", + "\n", + "We index the document in a vector database. This requires getting the documents, chunking them, embedding, and indexing them in a vector database. Then we retrieved relevant results based on the users' query.\n", + "\n", + "### We split the document into chunks of roughly 512 words" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZUph1JX41665", + "outputId": "6c63a93f-6999-47af-e704-d4a88727bc75" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m256.9/256.9 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.6/66.6 kB\u001b[0m \u001b[31m8.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m138.5/138.5 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "# For chunking let's use langchain to help us split the text\n", + "%pip install -qU langchain-text-splitters --quiet\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "uhXW7iHC1-Q6", + "outputId": "d68ac348-4b73-4c6a-a445-6c510bdb0881" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The text has been broken down in 91 chunks.\n" + ] + } + ], + "source": [ + "# Create basic configurations to chunk the text\n", + "text_splitter = RecursiveCharacterTextSplitter(\n", + " chunk_size=512,\n", + " chunk_overlap=50,\n", + " length_function=len,\n", + " is_separator_regex=False,\n", + ")\n", + "\n", + "# Split the text into chunks with some overlap\n", + "chunks_ = text_splitter.create_documents([text])\n", + "chunks = [c.page_content for c in chunks_]\n", + "print(f\"The text has been broken down in {len(chunks)} chunks.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8g0sE2hgbOs" + }, + "source": [ + "### Embed every text chunk\n", + "\n", + "Cohere embeddings are state-of-the-art." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "KEarMPEqgbOs", + "outputId": "7da0e06d-f637-4470-8e01-6de8249be64b" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "We just computed 91 embeddings.\n" + ] + } + ], + "source": [ + "# Because the texts being embedded are the chunks we are searching over, we set the input type as search_doc\n", + "model=\"embed-english-v3.0\"\n", + "response = co.embed(\n", + " texts= chunks,\n", + " model=model,\n", + " input_type=\"search_document\",\n", + " embedding_types=['float']\n", + ")\n", + "embeddings = response.embeddings.float\n", + "print(f\"We just computed {len(embeddings)} embeddings.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HM6vKeypgbOs" + }, + "source": [ + "### Store the embeddings in a vector database\n", + "\n", + "We use the simplest vector database ever: a python dictionary using `np.array()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sdW7M8HLvB-9" + }, + "outputs": [], + "source": [ + "# We use the simplest vector database ever: a python dictionary\n", + "!pip install numpy --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "H2srFH-IgbOs" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "vector_database = {i: np.array(embedding) for i, embedding in enumerate(embeddings)}\n", + "# { 0: array([...]), 1: array([...]), 2: array([...]), ..., 10: array([...]) }" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q6NGVurZgbOs" + }, + "source": [ + "## Given a user query, retrieve the relevant chunks from the vector database\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eC05yJQ7jlek" + }, + "source": [ + "### Define the user question" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Y2HTxspKgbOs" + }, + "outputs": [], + "source": [ + "query = \"Name everyone involved in writing the script, directing, and producing 'Dune: Part Two'?\"\n", + "\n", + "# Note: the relevant passage in the wikipedia page we're looking for is:\n", + "# \"[...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oULg1tOjjOW" + }, + "source": [ + "### Embed the user question\n", + "\n", + "Cohere embeddings are state-of-the-art." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "yrUuS6vXgbOs", + "outputId": "0c64a930-f817-43c2-d775-1d9145cb304e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "query_embedding: [-0.068603516, -0.02947998, -0.06274414, -0.015449524, -0.033294678, 0.0056877136, -0.047210693, 0.04714966, -0.024871826, 0.008148193, 0.0770874, 0.023880005, -0.058685303, -0.052520752, 0.012832642, 0.024398804, 0.0053215027, 0.035491943, 0.02961731, -0.0069847107, 0.01083374, -0.0011358261, -0.002199173, 0.018417358, 0.027389526, -0.002691269, -0.026535034, 0.015197754, 0.024368286, 0.03729248, 0.0057754517, -0.02229309, -0.014694214, 0.019989014, -0.0036315918, -0.013793945, 0.02835083, 0.006011963, 0.011428833, 0.008682251, 0.046142578, -0.040039062, -0.032196045, -0.002653122, -0.012580872, -0.0041618347, 0.03111267, -0.016799927, 0.014801025, -0.00030636787, -0.033050537, 0.033966064, -0.016021729, -0.025009155, -0.007534027, -0.017074585, 0.008415222, -0.10620117, 0.019195557, -0.015686035, -0.0043182373, -0.045440674, 0.05404663, 0.030776978, -0.014129639, -0.01499939, -0.007286072, 0.009933472, 0.06390381, 0.02444458, -0.010345459, 0.041931152, 0.032989502, -0.04522705, 0.056610107, 0.0068893433, -0.008911133, 0.012489319, 0.01675415, 0.020065308, 0.018753052, 0.022659302, -0.051849365, -0.04925537, 0.046325684, -0.005268097, 0.0026874542, -0.036712646, 0.009437561, -0.0037841797, -0.01473999, -0.034179688, -0.0011606216, 0.05026245, 0.0020771027, -0.016021729, -0.0044898987, 0.04168701, -0.015205383, 0.019210815, -0.012374878, -0.031311035, 0.03111267, -0.040100098, -0.016479492, 0.020446777, 0.010192871, 0.0037841797, -0.0023765564, 0.015220642, -0.016571045, -0.006454468, 0.037384033, -0.044555664, -0.008262634, 0.019546509, 0.009460449, 0.014701843, 0.02658081, -0.02078247, 0.015571594, 0.013153076, -0.010375977, 0.047912598, 0.005393982, -0.007911682, -0.019378662, 0.023529053, -0.0033550262, -0.04598999, -0.0052871704, 0.040252686, 0.011375427, 0.01550293, -0.004508972, 0.006515503, 0.003370285, -0.022766113, 0.00062561035, -0.0007596016, -0.0015277863, 0.0149002075, 0.061401367, 8.261204e-05, 0.06359863, -0.01537323, 0.007446289, 0.018814087, 0.02507019, 0.024215698, 0.006122589, 0.005886078, -0.03829956, 0.029037476, 0.07720947, 0.016921997, 0.022109985, 0.005958557, 0.028793335, 0.019485474, 0.015174866, 0.026153564, 0.032318115, 0.034210205, 0.027145386, -0.019515991, -0.018661499, 0.020477295, 0.008598328, -0.06573486, -0.037109375, 0.04043579, 0.030471802, -0.0010843277, 0.009757996, 0.026947021, 0.037017822, -0.018234253, -0.0115356445, 0.099365234, 0.027816772, -0.019927979, 0.0020961761, 0.013198853, -0.019073486, 2.7656555e-05, 0.041259766, 0.029510498, -0.016204834, 0.028137207, 0.039489746, 0.034698486, -0.03918457, -0.029418945, 0.02041626, 0.0073432922, -0.018569946, -0.009849548, 0.002861023, 0.030319214, -0.012886047, 0.014671326, -0.035827637, 0.007247925, -0.027709961, -0.022079468, 0.0012960434, 0.015426636, -0.01725769, 0.01525116, 0.025360107, -0.0077400208, -0.039916992, 0.029037476, -0.011154175, 0.007736206, -0.041748047, 0.05343628, 0.007286072, 0.0435791, 0.034301758, -0.047210693, 0.03552246, -0.015327454, 0.029922485, -0.018859863, 0.013053894, -0.028060913, 0.07757568, -0.020462036, 0.070739746, -0.010223389, 0.03604126, 0.02758789, -0.023284912, 0.012184143, 0.029144287, 0.023880005, -0.019378662, -0.0051116943, 0.0048675537, 0.01864624, -0.04397583, -0.007598877, 0.0713501, 0.0115737915, 0.002922058, 0.011619568, 0.017364502, 0.031921387, -0.0019664764, -0.008575439, 0.003484726, -0.09466553, 0.03475952, 0.026611328, -0.039520264, -0.0104522705, -0.005443573, -0.008392334, 0.012908936, 0.0043792725, -0.002456665, -0.028396606, -0.02027893, -0.0005569458, 0.027786255, 0.03427124, -0.0062332153, -0.018203735, 0.019241333, 0.07244873, -0.0028057098, 0.01234436, -0.0018787384, -0.027496338, 0.0015287399, -0.004032135, -0.013748169, -0.01878357, 0.0018053055, -0.01159668, 0.028213501, 0.004776001, 0.042388916, 0.0024280548, 0.017471313, -0.038085938, 0.026321411, 0.02973938, 0.06213379, 0.006401062, 0.036102295, -0.028121948, -0.00869751, -0.016693115, 0.029190063, 0.016784668, -0.008628845, 0.0039634705, -0.0035381317, 0.019500732, 0.025009155, -0.04547119, -0.003572464, 0.05215454, 0.067871094, -0.04257202, -0.02293396, -0.027175903, 0.05340576, 0.019226074, 0.039978027, 0.056121826, -0.028320312, -0.020217896, -0.035003662, 0.03225708, 0.028656006, 0.062347412, 0.12915039, -0.0137786865, 0.0022201538, -0.057434082, -0.04397583, -0.049865723, -0.013160706, -0.03353882, 0.006427765, -0.014823914, -0.008201599, -0.036346436, -0.037353516, -0.010528564, -0.015930176, -0.027572632, 0.0074272156, 0.004547119, -0.024414062, -0.018859863, -0.020095825, 0.029632568, -0.00067043304, -0.044036865, -0.0043411255, -0.005256653, -0.019195557, 0.022262573, -0.00020956993, -0.013877869, -0.011108398, -0.020324707, -0.015808105, -0.025039673, -0.009498596, 0.05090332, 0.0046195984, -0.017150879, 0.04309082, -0.029067993, 0.002670288, -0.00026249886, -0.032409668, -0.053100586, 0.012481689, -0.014633179, 0.0013475418, -0.034332275, 0.038330078, 0.014892578, -0.046936035, 0.021591187, -0.020385742, -0.0052604675, 0.02796936, 0.0014333725, 0.012077332, -0.0118255615, -0.005569458, 0.008491516, 0.009841919, 0.0031318665, -0.003408432, -0.007144928, 0.040374756, -0.0038928986, 0.005279541, -0.008415222, 0.031707764, 0.0140686035, -0.015029907, -0.02810669, -0.0078125, -0.030853271, -0.03201294, 0.021316528, -0.036193848, -0.0423584, 0.0072784424, 0.014801025, 0.0019607544, -0.012367249, -0.009056091, -0.021438599, -0.02645874, 0.038726807, -0.007549286, 0.0049591064, 0.019012451, 0.017791748, -0.009185791, 0.04006958, 0.003107071, -0.0075302124, -0.010375977, -0.009246826, -0.02130127, -0.0056762695, -0.0076789856, 0.010009766, -0.010536194, 0.041107178, 0.0021133423, 0.029891968, 0.01626587, 0.042236328, -0.02784729, -0.032836914, 0.0317688, 0.045715332, 0.000116825104, 0.028030396, 0.007205963, 0.012512207, -0.035583496, -0.048034668, -0.023529053, -0.04953003, 0.0345459, -0.048339844, -0.060272217, -0.004512787, 0.04425049, 0.0076141357, 0.029510498, 0.007396698, 0.003353119, -0.038726807, 0.07183838, -0.026901245, -0.023529053, -0.038085938, 0.068725586, 0.018096924, -0.013534546, 0.05883789, -0.016113281, 0.017944336, 0.041046143, 0.022918701, 0.036499023, 0.015296936, -0.04916382, 0.0075683594, -0.011390686, 0.009735107, -0.0070152283, 0.003129959, -0.032562256, 0.0003478527, -0.0036640167, -0.006893158, -0.016098022, -0.034332275, 0.037750244, -0.010269165, 0.016494751, -0.02394104, 0.03753662, -0.022644043, -0.0008234978, 0.001001358, -0.048217773, 0.04989624, 0.0078125, 0.0044937134, 0.027038574, 0.04736328, -0.02973938, -0.011726379, 0.01348114, 0.021408081, 0.00844574, -0.03741455, -0.015686035, -0.040893555, 0.001452446, -0.025405884, 0.07348633, 0.038238525, -0.019958496, 0.023071289, -0.016403198, -0.08105469, 0.0071029663, -0.019088745, 5.8174133e-05, -0.005569458, 0.01399231, 0.02255249, 0.011222839, 0.00028824806, 0.0066184998, 0.0017499924, -0.009864807, -0.0115737915, 0.053100586, 0.0065231323, 0.001865387, -0.026428223, 0.03692627, 0.025390625, 0.022613525, 0.018722534, 0.007675171, -0.03439331, 0.041625977, -0.01789856, -0.041046143, 0.0051460266, 0.04144287, 0.048553467, 0.054595947, -0.01108551, -0.033935547, -0.026275635, -0.0118255615, -0.021362305, -0.009841919, -0.00724411, 0.028900146, 0.009887695, -0.023803711, 0.016311646, 0.018798828, -0.03668213, 0.046844482, 0.010696411, -0.014717102, -0.008110046, -0.004589081, -0.0028076172, -0.050811768, -0.017196655, -0.03491211, 0.0074005127, -0.038909912, 0.032440186, -0.034362793, -0.008682251, 0.032928467, -0.04626465, -0.009666443, 0.018951416, 0.031951904, -0.003791809, 0.02015686, -0.05532837, -0.005683899, -0.00054216385, -0.0034332275, 0.008659363, 0.02130127, -0.038879395, -0.0033397675, -0.03866577, -0.0049934387, 0.017944336, 0.001496315, 0.019485474, -0.004348755, 0.00046491623, 0.0007157326, 0.035614014, -0.027694702, 0.03692627, -0.008491516, 0.0524292, -0.016662598, -0.0017795563, -0.021575928, -0.018753052, -0.049346924, -0.06652832, 0.04272461, 0.03186035, 0.0011978149, 0.03463745, 0.024002075, 0.02607727, 0.020446777, 0.0256958, 0.026855469, 0.0074005127, -0.067993164, 0.017944336, -0.0039482117, 0.05496216, -0.041412354, 0.014175415, 0.02444458, -0.026412964, 0.057403564, -0.026779175, 0.023254395, 0.03945923, 0.033569336, -0.030258179, -0.039093018, -0.036468506, 0.017105103, 0.009635925, 0.025497437, 0.04156494, -0.02571106, -0.0010414124, -0.005630493, -0.016448975, -0.026733398, 0.001326561, -0.042022705, 0.0012521744, -0.041259766, -0.12182617, -0.03857422, 0.12548828, -0.005947113, -0.020736694, -0.0033855438, 0.03778076, -0.033813477, 0.038970947, 0.003921509, 0.011810303, 0.031982422, -0.032562256, -0.002653122, -0.025009155, -0.03805542, -0.016998291, 0.018173218, 0.0158844, 0.0011739731, 0.048217773, -0.020401001, 0.044708252, -0.017318726, 0.014457703, -0.041809082, 0.010543823, 0.041931152, 0.076293945, -0.054779053, 0.060272217, -0.046936035, 0.02949524, 0.00554657, 0.041534424, -0.013046265, -0.056152344, 0.010406494, 0.02973938, -0.023727417, -0.022476196, -0.024734497, -0.013168335, 0.060424805, 0.011787415, 0.018997192, -0.043426514, -0.00077724457, -0.010154724, 0.017150879, -0.01171875, -0.022476196, 0.0034255981, -0.0026454926, 0.004837036, -0.0043296814, 0.02619934, -0.021560669, -0.039733887, -0.022415161, -0.06817627, -0.023223877, -0.018585205, -0.015319824, 0.012588501, 0.0064353943, -0.013748169, 0.043304443, 0.002626419, -0.029373169, -0.016784668, -0.026184082, 0.05847168, 0.034179688, 0.03842163, -0.05493164, -0.017486572, 0.016540527, 0.03164673, 0.089904785, 0.013534546, -0.07684326, -0.024108887, 0.07434082, 0.030395508, 0.007091522, 0.07373047, 0.012527466, -0.010856628, -0.01828003, -0.045196533, 0.00065279007, -0.0637207, 0.010726929, 0.023880005, -0.0030708313, -0.012298584, 0.027236938, -0.04928589, 0.023071289, 0.008674622, -0.023529053, -0.015838623, -0.010543823, 0.012168884, 0.014854431, -0.05834961, -0.06088257, -0.012313843, 0.035461426, 0.02027893, 0.019348145, -0.014602661, -0.02104187, -0.0309906, 0.001405716, -0.019973755, -0.00157547, -0.003944397, 0.0009326935, -0.02078247, -0.015731812, -0.044433594, 0.03390503, 0.057159424, 0.018585205, -0.023895264, -0.0057029724, 0.0049552917, 0.013412476, 0.022399902, 0.010154724, 0.0519104, 0.06591797, 0.018341064, 0.012161255, -0.05810547, -0.043304443, -0.031173706, 0.0023860931, -0.003944397, 0.11425781, -0.031036377, 0.019989014, -0.038635254, -0.025939941, 0.035064697, 0.041168213, 0.03161621, -0.069885254, -0.04537964, 0.028945923, -0.023162842, 0.019226074, -0.028442383, 0.015594482, -0.019256592, -0.0046463013, 0.034240723, 0.009124756, 0.05718994, 0.031219482, 0.02154541, 0.009590149, 0.00076818466, 0.04849243, -0.029129028, -0.03375244, -0.023391724, -0.028381348, -0.029708862, -0.0132369995, 0.010353088, 0.020263672, -0.030807495, 0.01007843, -0.03704834, 0.023376465, -0.03665161, 0.03741455, 0.015144348, 0.057281494, 0.03137207, 0.048431396, 0.021194458, 0.008110046, -0.03540039, -0.015312195, 0.022384644, 0.0065956116, 0.008056641, 0.0018348694, -0.009246826, 0.030380249, 0.0003862381, 0.0051841736, 0.04486084, 0.017807007, 0.0026130676, 0.07977295, 0.05419922, 0.062194824, 0.02633667, 0.024841309, -0.041625977, -0.005897522, 0.04031372, -0.055908203, 0.0026226044, -0.05340576, -0.05496216, 0.011474609, -0.006954193, -0.013122559, 0.019714355, -0.07159424, 0.031173706, 0.0034255981, -0.0034103394, 0.0440979, 0.011779785, -0.007827759, -0.03173828, -0.020950317, -0.030166626, -0.035308838, 0.030792236, 0.04525757, -0.028701782, -0.011100769, -0.02331543, -0.0357666, -0.025680542, 0.0011911392, 0.01940918, 0.05706787, 0.028381348, 0.007133484, -0.07733154, -0.007686615, 0.03869629, 0.0066833496, 0.008842468, 0.03439331, -0.014282227, 0.0357666, -0.004737854, -0.039794922, -0.0070381165, 0.02670288, 0.0107421875, 0.016189575, -0.06555176, -0.0138549805, 0.0008363724, -0.016693115, 0.006904602, -0.020263672, -0.030426025, 0.008453369, -0.046173096, -0.01802063, -0.013595581, -0.0044288635, -0.0039978027, -0.0044898987, 0.0007619858, 0.003921509, 0.0053977966, 0.020385742, -0.012329102, -0.023803711, -0.0057525635, 0.038330078, -0.014549255, -0.06298828, -0.047607422, 0.039245605, -0.06781006, -0.035217285, -0.009056091, 0.019927979, -0.003932953, -0.020309448, -0.017044067, 0.018127441, -8.624792e-05, -0.043182373, 0.009590149, 0.035308838, 0.031951904, 0.0011615753, -0.042022705, 0.079956055, 0.026687622, 0.013542175, -0.0074157715, -0.00983429, -0.0022563934, 0.07373047, 0.059387207, 0.03488159, 0.0071372986, -0.06427002, -0.0546875, -0.02482605, 0.11071777, -0.021072388, 0.01626587, -0.049713135, 0.061553955, -0.016860962, 0.051971436, -0.012962341, -0.0011711121, -0.014198303, -0.0061149597, -0.005836487, 0.00022387505, -0.027618408, 0.019836426, 0.009933472, 0.02368164, -0.020309448, -0.0049591064, -0.008628845, -0.03253174, -0.017684937, 0.02468872, -0.0023498535, 0.01448822, 0.061920166, 0.031707764, -0.0026416779, -0.040985107, -0.06335449, -0.036071777, 0.05404663, -0.0044136047, -0.0146102905, -0.0033416748, 0.028671265, -0.012771606, -0.0016565323, -0.0038909912, -0.02407837, -0.009857178, 0.0014467239, -0.008720398, -0.006011963, 0.032073975, -0.033325195, 0.014862061, -0.017227173, -0.018753052, -0.0060424805, 0.022567749, -0.017654419, -0.017562866, -0.07244873, -0.0881958, 0.050476074, 0.02609253, -0.032409668, 0.07458496, 0.009399414, 0.009117126, -0.031051636, -0.03451538, -0.004219055, -0.05718994, 0.020080566, -0.025421143, -0.010948181, 0.06341553, -0.009231567, -0.021697998, -0.009719849, 0.012802124, -0.020370483, 0.0034389496, 0.018859863, -0.025680542, 0.0013141632, 0.068603516, -0.021026611, 0.021881104, -0.0395813, -0.0019073486, 0.0056037903, -0.032348633]\n" + ] + } + ], + "source": [ + "# Because the text being embedded is the search query, we set the input type as search_query\n", + "response = co.embed(\n", + " texts=[query],\n", + " model=model,\n", + " input_type=\"search_query\",\n", + " embedding_types=['float']\n", + ")\n", + "query_embedding = response.embeddings.float[0]\n", + "print(\"query_embedding: \", query_embedding)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8K8B87CGgbOt" + }, + "source": [ + "### Retrieve the most relevant chunks from the vector database\n", + "\n", + "We use cosine similarity to find the most similar chunks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "nik3es32gbOt", + "outputId": "a1c30024-52e1-42c7-8836-a2c590559aca" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "similarity scores: [0.6953257882233425, 0.3713410510180273, 0.46501499776898964, 0.5448546916785195, 0.4014738351361969, 0.3231420292334584, 0.3179003053384008, 0.42799691553367775, 0.18882594531435784, 0.36868801306504106, 0.3404040737300553, 0.3852837621219358, 0.2600249419491577, 0.3723244353775111, 0.3631492691137214, 0.47574774051439606, 0.40415422750911745, 0.4149923346201023, 0.5014741934381444, 0.3549433331883204, 0.32072714802512714, 0.14770872479410424, 0.585277816615252, 0.6999636953772764, 0.7722295084104617, 0.4895347049465806, 0.5170096485954725, 0.7137817366881455, 0.5224900699612323, 0.5914632581598285, 0.2657897083381463, 0.6462342489537262, 0.6317222315431096, 0.5982303530756702, 0.5138265091630297, 0.41385121172723643, 0.4293941094100836, 0.4173182546482015, 0.42621236706314475, 0.4428474375355954, 0.35058541576139896, 0.3578709652019502, 0.3930157841938308, 0.3564608202848675, 0.23016661533167404, 0.4933441863421645, 0.41037089239250985, 0.39993051898770193, 0.3119997063424595, 0.2677143729521374, 0.3700866951454496, 0.46727994925061545, 0.4393343280374425, 0.42111290117172434, 0.4485349189824285, 0.4710573736688592, 0.24169956903740436, 0.3840442910806355, 0.14284631817675886, 0.5381588054138154, 0.431113882725076, 0.5189547209048608, 0.3950667224233914, 0.32429768756510174, 0.4370358125161736, 0.18727062244331039, 0.5206375682478743, 0.5175737635701252, 0.5326043981628349, 0.45586923626994363, 0.21667338125532032, 0.16459878595959285, 0.22236726481673777, 0.5187259906958807, 0.2884444442338396, 0.286407544555338, 0.2313840178160818, 0.2057731158935257, 0.5973876998341746, 0.42904243401792086, 0.4081217538000544, 0.5330523063972133, 0.45080561486977405, 0.414703452285757, 0.2569028899107211, 0.5087916806929323, 0.14159076456040554, 0.46505779053352697, 0.556364222182839, 0.35464351181035236, 0.40174477023626]\n", + "Here are the indices of the top 10 chunks after retrieval: [24 27 23 0 31 32 33 78 29 22]\n", + "Here are the top 10 chunks after retrieval: \n", + "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", + "== that.\"On October 26, 2021, Legendary officially greenlit Dune: Part Two, with a spokesperson for the company stating, \"We would not have gotten to this point without the extraordinary vision of Denis and the amazing work of his talented crew, the writers, our stellar cast, our partners at Warner Bros., and of course the fans! Here's to more Dune.\" Production work had occurred back-to-back with the first film, as Villeneuve and his wife Lapointe immediately took a flight to Budapest in order to begin\n", + "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n", + "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", + "== Eric Roth was hired to co-write the screenplay in April 2017 for the Dune films, and Jon Spaihts was later confirmed to be co-writing the script alongside Roth and Villeneuve. Game of Thrones language creator David Peterson was confirmed to be developing languages for the film in April 2019. Villeneuve and Peterson had created the Chakobsa language, which was used by actors on set. In November 2019, Spaihts stepped down as showrunner for Dune: Prophecy to focus on Dune: Part Two. In June 2020, Greig Fraser\n", + "== on Dune: Part Two. In June 2020, Greig Fraser said, \"It's a fully formed story in itself with places to go. It's a fully standalone epic film that people will get a lot out of when they see it\". Between the release of Dune and the confirmation of Dune: Part Two, Villeneuve started working the script in a way that production could begin immediately once the film was greenlit. By February 2021, Roth created a full treatment for the sequel, with writing beginning that August. He confirmed that Feyd-Rautha\n", + "== that August. He confirmed that Feyd-Rautha would appear in the film, and stated he will be a \"very important character\". In March 2022, Villeneuve had mostly finished writing the screenplay. Craig Mazin and Roth wrote additional literary material for the film.Villeneuve stated that the film would continue directly from the first, and specifically described it as being the \"second part.\" He described the film as being an \"epic war movie\", adding that while the first film was more \"contemplative\", the second\n", + "== On the review aggregator website Rotten Tomatoes, 93% of 378 critics' reviews are positive, with an average rating of 8.4/10. The website's consensus reads: \"Visually thrilling and narratively epic, Dune: Part Two continues Denis Villeneuve's adaptation of the beloved sci-fi series in spectacular form.\" Metacritic, which uses a weighted average, assigned the film a score of 79 out of 100, based on 62 critics, indicating \"generally favorable\" reviews. Audiences surveyed by CinemaScore gave the film an\n", + "== theatrical experience is at the very heart of the cinematic language for me.\" With Dune: Part Two being greenlit, Villeneuve said that his primary concern was to complete the filming as soon as possible, with the earliest he expected to start in the last quarter of 2022. However, he noted that production would be facilitated by the work already established on the first film, which would help expedite production.\n", + "== By November 2016, Legendary Pictures had obtained the film and TV rights for the Dune franchise, based on the eponymous 1965 novel by Frank Herbert. Vice chair of worldwide production for Legendary Mary Parent began discussing with Denis Villeneuve about directing a film adaptation, quickly hiring him after realizing his passion for Dune. By February 2018, Villeneuve was confirmed to be hired as director, and intended to adapt the novel as a two-part film series. Villeneuve ultimately secured a two-film\n" + ] + } + ], + "source": [ + "def cosine_similarity(a, b):\n", + " return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))\n", + "\n", + "# Calculate similarity between the user question & each chunk\n", + "similarities = [cosine_similarity(query_embedding, chunk) for chunk in embeddings]\n", + "print(\"similarity scores: \", similarities)\n", + "\n", + "# Get indices of the top 10 most similar chunks\n", + "sorted_indices = np.argsort(similarities)[::-1]\n", + "\n", + "# Keep only the top 10 indices\n", + "top_indices = sorted_indices[:10]\n", + "print(\"Here are the indices of the top 10 chunks after retrieval: \", top_indices)\n", + "\n", + "# Retrieve the top 10 most similar chunks\n", + "top_chunks_after_retrieval = [chunks[i] for i in top_indices]\n", + "print(\"Here are the top 10 chunks after retrieval: \")\n", + "for t in top_chunks_after_retrieval:\n", + " print(\"== \" + t)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qzcpds3VgbOt" + }, + "source": [ + "## Step 2 - Rerank the chunks retrieved from the vector database\n", + "\n", + "We rerank the 10 chunks retrieved from the vector database. Reranking boosts retrieval accuracy.\n", + "\n", + "Reranking lets us go from 10 chunks retrieved from the vector database, to the 3 most relevant chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2J4LywVygbOt", + "outputId": "7a4c89bf-fc5e-409f-9304-fce006b9d8bf" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the top 3 chunks after rerank: \n", + "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", + "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", + "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n" + ] + } + ], + "source": [ + "response = co.rerank(\n", + " query=query,\n", + " documents=top_chunks_after_retrieval,\n", + " top_n=3,\n", + " model=\"rerank-english-v2.0\",\n", + ")\n", + "\n", + "top_chunks_after_rerank = [result.document['text'] for result in response]\n", + "print(\"Here are the top 3 chunks after rerank: \")\n", + "for t in top_chunks_after_rerank:\n", + " print(\"== \" + t)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KuPL0VUXgbOt" + }, + "source": [ + "## Step 3 - Generate the model final answer, given the retrieved and reranked chunks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "oCNXWH8GgbOt" + }, + "outputs": [], + "source": [ + "# preamble containing instructions about the task and the desired style for the output.\n", + "preamble = \"\"\"\n", + "## Task & Context\n", + "You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n", + "\n", + "## Style Guide\n", + "Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BevatShtgbOt", + "outputId": "af71f4a9-787a-4ee3-9598-20692fb3bf16" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Final answer:\n", + "Here are the key crew members involved in 'Dune: Part Two':\n", + "\n", + "- Denis Villeneuve: director and producer\n", + "- Jon Spaihts: co-writer of the screenplay\n", + "- Mary Parent and Cale Boyter: producers \n", + "- Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Richard P. Rubinstein, John Harrison, Herbert W. Gain and Kevin J. Anderson: executive producers \n", + "- Joe Walker: editor\n", + "- Brad Riker: supervising art director\n", + "- Patrice Vermette: production designer\n", + "- Paul Lambert: visual effects supervisor\n", + "- Gerd Nefzer: special effects supervisor\n", + "- Thomas Struthers: stunt coordinator. \n", + "\n", + "A number of crew members from the first film returned for the sequel, which is set to be released in 2024.\n" + ] + } + ], + "source": [ + "# retrieved documents\n", + "documents = [\n", + " {\"title\": \"chunk 0\", \"snippet\": top_chunks_after_rerank[0]},\n", + " {\"title\": \"chunk 1\", \"snippet\": top_chunks_after_rerank[1]},\n", + " {\"title\": \"chunk 2\", \"snippet\": top_chunks_after_rerank[2]},\n", + " ]\n", + "\n", + "# get model response\n", + "response = co.chat(\n", + " message=query,\n", + " documents=documents,\n", + " preamble=preamble,\n", + " model=\"command-r\",\n", + " temperature=0.3\n", + ")\n", + "\n", + "print(\"Final answer:\")\n", + "print(response.text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "20wcn-EjlXZd" + }, + "source": [ + "Note: this is indeed the answer you'd expect, and here was the passage of text in wikipedia explaining it!\n", + "\n", + "\" [...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RoSVDXSsgbOt" + }, + "source": [ + "## Bonus: Citations come for free with Cohere! 🎉\n", + "\n", + "At Cohere, all RAG calls come with... precise citations! 🎉\n", + "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", + "These citations make it easy to check where the model’s generated response claims are coming from. \n", + "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", + "These citations are optional — you can decide to ignore them.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BVTuQdmDgbOt", + "outputId": "f843b262-d8bb-45ba-cbfb-9915da104eda" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Citations that support the final answer:\n", + "{'start': 63, 'end': 79, 'text': 'Denis Villeneuve', 'document_ids': ['doc_0']}\n", + "{'start': 81, 'end': 102, 'text': 'director and producer', 'document_ids': ['doc_0']}\n", + "{'start': 105, 'end': 116, 'text': 'Jon Spaihts', 'document_ids': ['doc_0']}\n", + "{'start': 118, 'end': 145, 'text': 'co-writer of the screenplay', 'document_ids': ['doc_0']}\n", + "{'start': 148, 'end': 159, 'text': 'Mary Parent', 'document_ids': ['doc_1']}\n", + "{'start': 164, 'end': 175, 'text': 'Cale Boyter', 'document_ids': ['doc_1']}\n", + "{'start': 177, 'end': 186, 'text': 'producers', 'document_ids': ['doc_1']}\n", + "{'start': 190, 'end': 204, 'text': 'Tanya Lapointe', 'document_ids': ['doc_1']}\n", + "{'start': 206, 'end': 219, 'text': 'Brian Herbert', 'document_ids': ['doc_1']}\n", + "{'start': 221, 'end': 234, 'text': 'Byron Merritt', 'document_ids': ['doc_1']}\n", + "{'start': 236, 'end': 247, 'text': 'Kim Herbert', 'document_ids': ['doc_1']}\n", + "{'start': 249, 'end': 260, 'text': 'Thomas Tull', 'document_ids': ['doc_1']}\n", + "{'start': 262, 'end': 283, 'text': 'Richard P. Rubinstein', 'document_ids': ['doc_1']}\n", + "{'start': 285, 'end': 298, 'text': 'John Harrison', 'document_ids': ['doc_1']}\n", + "{'start': 300, 'end': 315, 'text': 'Herbert W. Gain', 'document_ids': ['doc_1']}\n", + "{'start': 320, 'end': 337, 'text': 'Kevin J. Anderson', 'document_ids': ['doc_1']}\n", + "{'start': 339, 'end': 358, 'text': 'executive producers', 'document_ids': ['doc_1']}\n", + "{'start': 362, 'end': 372, 'text': 'Joe Walker', 'document_ids': ['doc_2']}\n", + "{'start': 374, 'end': 380, 'text': 'editor', 'document_ids': ['doc_2']}\n", + "{'start': 383, 'end': 393, 'text': 'Brad Riker', 'document_ids': ['doc_2']}\n", + "{'start': 395, 'end': 419, 'text': 'supervising art director', 'document_ids': ['doc_2']}\n", + "{'start': 422, 'end': 438, 'text': 'Patrice Vermette', 'document_ids': ['doc_2']}\n", + "{'start': 440, 'end': 459, 'text': 'production designer', 'document_ids': ['doc_2']}\n", + "{'start': 462, 'end': 474, 'text': 'Paul Lambert', 'document_ids': ['doc_2']}\n", + "{'start': 476, 'end': 501, 'text': 'visual effects supervisor', 'document_ids': ['doc_2']}\n", + "{'start': 504, 'end': 515, 'text': 'Gerd Nefzer', 'document_ids': ['doc_2']}\n", + "{'start': 517, 'end': 543, 'text': 'special effects supervisor', 'document_ids': ['doc_2']}\n", + "{'start': 546, 'end': 562, 'text': 'Thomas Struthers', 'document_ids': ['doc_2']}\n", + "{'start': 564, 'end': 582, 'text': 'stunt coordinator.', 'document_ids': ['doc_2']}\n", + "{'start': 686, 'end': 691, 'text': '2024.', 'document_ids': ['doc_0']}\n" + ] + } + ], + "source": [ + "print(\"Citations that support the final answer:\")\n", + "for cite in response.citations:\n", + " print(cite)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "IueXaIJggbOu", + "outputId": "c816af51-74be-42c9-e94e-9820bbf95f79" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the key crew members involved in 'Dune: Part Two':\n", + "\n", + "- **Denis Villeneuve**[1]: **director and producer**[1]\n", + "- **Jon Spaihts**[1]: **co-writer of the screenplay**[1]\n", + "- **Mary Parent**[2] and **Cale Boyter**[2]: **producers**[2] \n", + "- **Tanya Lapointe**[2], **Brian Herbert**[2], **Byron Merritt**[2], **Kim Herbert**[2], **Thomas Tull**[2], **Richard P. Rubinstein**[2], **John Harrison**[2], **Herbert W. Gain**[2] and **Kevin J. Anderson**[2]: **executive producers**[2] \n", + "- **Joe Walker**[3]: **editor**[3]\n", + "- **Brad Riker**[3]: **supervising art director**[3]\n", + "- **Patrice Vermette**[3]: **production designer**[3]\n", + "- **Paul Lambert**[3]: **visual effects supervisor**[3]\n", + "- **Gerd Nefzer**[3]: **special effects supervisor**[3]\n", + "- **Thomas Struthers**[3]: **stunt coordinator.**[3] \n", + "\n", + "A number of crew members from the first film returned for the sequel, which is set to be released in **2024.**[1]\n", + "\n", + "[1] source: \"Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\"\n", + "[2] source: \"stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\"\n", + "[3] source: \"series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\"\n" + ] + } + ], + "source": [ + "def insert_citations_in_order(text, citations):\n", + " \"\"\"\n", + " A helper function to pretty print citations.\n", + " \"\"\"\n", + " offset = 0\n", + " document_id_to_number = {}\n", + " citation_number = 0\n", + " modified_citations = []\n", + "\n", + " # Process citations, assigning numbers based on unique document_ids\n", + " for citation in citations:\n", + " citation_numbers = []\n", + " for document_id in sorted(citation[\"document_ids\"]):\n", + " if document_id not in document_id_to_number:\n", + " citation_number += 1 # Increment for a new document_id\n", + " document_id_to_number[document_id] = citation_number\n", + " citation_numbers.append(document_id_to_number[document_id])\n", + "\n", + " # Adjust start/end with offset\n", + " start, end = citation['start'] + offset, citation['end'] + offset\n", + " placeholder = ''.join([f'[{number}]' for number in citation_numbers])\n", + " # Bold the cited text and append the placeholder\n", + " modification = f'**{text[start:end]}**{placeholder}'\n", + " # Replace the cited text with its bolded version + placeholder\n", + " text = text[:start] + modification + text[end:]\n", + " # Update the offset for subsequent replacements\n", + " offset += len(modification) - (end - start)\n", + "\n", + " # Prepare citations for listing at the bottom, ensuring unique document_ids are listed once\n", + " unique_citations = {number: doc_id for doc_id, number in document_id_to_number.items()}\n", + " citation_list = '\\n'.join([f'[{doc_id}] source: \"{documents[doc_id - 1][\"snippet\"]}\"' for doc_id, number in sorted(unique_citations.items(), key=lambda item: item[1])])\n", + " text_with_citations = f'{text}\\n\\n{citation_list}'\n", + "\n", + " return text_with_citations\n", + "\n", + "\n", + "print(insert_citations_in_order(response.text, response.citations))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Kp4c_HkYIEn_" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "hackathon_docs_3", + "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": 0 +} diff --git a/notebooks/Embed_Jobs_Semantic_Search.ipynb b/notebooks/Embed_Jobs_Semantic_Search.ipynb index 4b7ba4f9..9043c176 100644 --- a/notebooks/Embed_Jobs_Semantic_Search.ipynb +++ b/notebooks/Embed_Jobs_Semantic_Search.ipynb @@ -1,366 +1,364 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "ig3hmpIt8ptJ" - }, - "source": [ - "# Semantic Search with Cohere Embed Jobs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "fc94ylzpucDm" - }, - "outputs": [], - "source": [ - "# TODO: upgrade to \"cohere>5\"", -"! pip install \"cohere<5\" hnswlib -q" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Qu9a_jwZ5Zop" - }, - "outputs": [], - "source": [ - "import time\n", - "import cohere\n", - "import hnswlib\n", - "co = cohere.Client('COHERE_API_KEY')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Fgqhh1kk8mnY" - }, - "source": [ - "## Step 1: Upload a dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "kogkZnDEnK8B", - "outputId": "646b4508-8111-42ad-a9b2-3425da1ae5ff" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "uploading file, starting validation...\n", - "sample-file-hca4x0 was uploaded\n", - "...\n" - ] - } - ], - "source": [ - "# Upload a dataset for embed jobs\n", - "# This sample dataset has wikipedia articles on the following: Youtube, United States, United Kingdom, Elizabeth II, Wikipedia, 2022 FIFA World Cup, Microsoft Office, India, Christiano Ronaldo, Cleopatra, Instagram, Facebook, and Ukraine\n", - "\n", - "dataset_file_path = \"data/embed_jobs_sample_data.jsonl\" # Full path - https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/embed_jobs_sample_data.jsonl\n", - "\n", - "ds=co.create_dataset(\n", - "\tname='sample_file',\n", - "\tdata=open(dataset_file_path, 'rb'),\n", - "\tkeep_fields = ['id','wiki_id'],\n", - "\tdataset_type=\"embed-input\"\n", - "\t)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "3lAS4bcvCplJ", - "outputId": "5e1fcd0b-4880-43ed-d8a4-03148b2ef047" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cohere.Dataset {\n", - "\tid: sample-file-hca4x0\n", - "\tname: sample_file\n", - "\tdataset_type: embed-input\n", - "\tvalidation_status: validated\n", - "\tcreated_at: 2024-01-13 02:51:48.215973\n", - "\tupdated_at: 2024-01-13 02:51:48.215973\n", - "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/f8bd5ab1-ccdf-45e6-9717-23b8be1ff39d/sample-file-hca4x0/000_embed_jobs_sample_data.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T025159Z&X-Goog-Expires=14399&X-Goog-Signature=7f9ed7cb27988e4bf447167160b25940cd106859d1282919604a0d74b882681b5aaa3245f97555bb61ddca7fd9c02fb0bba8391433c70aeb2118607dfd534db444097c5ae9c8d07e66bf6723a64634f5d6f5b2500c82e351807203f5fd3c278b2584c258b4c6afc6ee191e63bcd346e3dd2c7fd4b171c2d3ddfe8e6e68c2522111b6f63e125a052be9ebe3302903f4bef9cd165c8e075b168e621c7c61177a0973bb470cc3535457078e18b338884fb303792a1ba3161ab5ca5ce2adca5676754ee1a735891ccbf64cca03d3fdcabdcccd0d201600b8c70e13487bf897f2b88424cc736f8bf8756ec835b09dacf0aa20dc8151d9249b21d4ca4de82144fcd8be&X-Goog-SignedHeaders=host']\n", - "\tvalidation_error: None\n", - "\tvalidation_warnings: []\n", - "}\n" - ] - } - ], - "source": [ - "print(ds.await_validation())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "QgD2QCJk9kUN" - }, - "source": [ - "## Step 2: Create embeddings via Cohere's Embed Jobs endpoint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "yMYoU9y55m2D", - "outputId": "fd58014d-a9e3-4a3f-ca4b-966880dec412" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "...\n", - "...\n" - ] - } - ], - "source": [ - "# Dataset has been uploaded, create an embed job and specify the input type as \"search document\" since this will live in your Pinecone DB\n", - "job = co.create_embed_job(\n", - " dataset_id=ds.id,\n", - " input_type='search_document' ,\n", - " model='embed-english-v3.0', \n", - " embeddings_types=['float'])\n", - "\n", - "job.wait() # poll the server until the job is completed " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "LEevvN2XCUpR", - "outputId": "d123c0a4-0c6a-4235-9ba8-658d5d3ec358" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cohere.EmbedJob {\n", - "\tjob_id: 792bbc1a-561b-48c2-8a97-0c80c1914ea8\n", - "\tstatus: complete\n", - "\tcreated_at: 2024-01-13T02:53:31.879719Z\n", - "\tinput_dataset_id: sample-file-hca4x0\n", - "\toutput_urls: None\n", - "\tmodel: embed-english-v3.0\n", - "\ttruncate: RIGHT\n", - "\tpercent_complete: 100\n", - "\toutput: cohere.Dataset {\n", - "\tid: embeded-sample-file-drtjf9\n", - "\tname: embeded-sample-file\n", - "\tdataset_type: embed-result\n", - "\tvalidation_status: validated\n", - "\tcreated_at: 2024-01-13 02:53:33.569362\n", - "\tupdated_at: 2024-01-13 02:53:33.569362\n", - "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/f8bd5ab1-ccdf-45e6-9717-23b8be1ff39d/embeded-sample-file-drtjf9/001_embeded-sample-file.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T025352Z&X-Goog-Expires=14399&X-Goog-Signature=927d2d73947058c95cd73f813e87e81416163dd0ccba1d5ce064a186fdc732550a605ff2122c9087fcc8e16dded9836084be532dac59622f73cb625fa1014fa9b1f9b702ca02be50006d8e2b2239870e3c765f7f8bd4964ccc74f4d9cc28672cd22c0d47008b112bd787eaab19692a5d9d724899f6aac088facdbe6d3b9d74f929fa07e76126656a5b0635a9793d9e85e692ca2d1d40f406869a53aa2e7390570d67e602fc5ea1741686176ce857112d5d68dee1b2fc62a436cd244890ec7c5901941cb10b01c2c41d6eba67dc393370a7c47526a7272f1f70f880b5fea2f69cb4546a633440a538fad7b92fdeb28d98aec1680cafc89142053da915268ea039&X-Goog-SignedHeaders=host']\n", - "\tvalidation_error: None\n", - "\tvalidation_warnings: []\n", - "}\n", - "}\n" - ] - } - ], - "source": [ - "print(job)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ZVf1njJ4952G" - }, - "source": [ - "## Step 3: Download and prepare the embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "0FdyxbcR5uci" - }, - "outputs": [], - "source": [ - "# Save down the output of the job\n", - "embeddings_file_path = 'embed_jobs_output.csv'\n", - "output_dataset=co.get_dataset(job.output.id)\n", - "output_dataset.save(filepath=embeddings_file_path, format=\"csv\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "VvheIBdJ6FC_" - }, - "outputs": [], - "source": [ - "# Add the results\n", - "embeddings=[]\n", - "texts=[]\n", - "for record in output_dataset:\n", - " embeddings.append(record['embeddings']['float'])\n", - " texts.append(record['text'])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-O-Yz8MS-DFz" - }, - "source": [ - "## Step 4: Initialize Hnwslib index and add embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "_vGfX8aQ9uD1" - }, - "outputs": [], - "source": [ - "# Create the hnsw index\n", - "index = hnswlib.Index(space='ip', dim=1024)\n", - "index.init_index(max_elements=len(embeddings), ef_construction=512, M=64)\n", - "index.add_items(embeddings,list(range(len(embeddings))))" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "ig3hmpIt8ptJ" + }, + "source": [ + "# Semantic Search with Cohere Embed Jobs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Qu9a_jwZ5Zop" + }, + "outputs": [], + "source": [ + "import time\n", + "import cohere\n", + "import hnswlib\n", + "co = cohere.Client('COHERE_API_KEY')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fgqhh1kk8mnY" + }, + "source": [ + "## Step 1: Upload a dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "kogkZnDEnK8B", + "outputId": "646b4508-8111-42ad-a9b2-3425da1ae5ff" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "yN5qBoVX-M7g" - }, - "source": [ - "## Step 5: Query the index and rerank the results" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "uploading file, starting validation...\n", + "sample-file-hca4x0 was uploaded\n", + "...\n" + ] + } + ], + "source": [ + "# Upload a dataset for embed jobs\n", + "# This sample dataset has wikipedia articles on the following: Youtube, United States, United Kingdom, Elizabeth II, Wikipedia, 2022 FIFA World Cup, Microsoft Office, India, Christiano Ronaldo, Cleopatra, Instagram, Facebook, and Ukraine\n", + "\n", + "dataset_file_path = \"data/embed_jobs_sample_data.jsonl\" # Full path - https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/embed_jobs_sample_data.jsonl\n", + "\n", + "ds=co.create_dataset(\n", + "\tname='sample_file',\n", + "\tdata=open(dataset_file_path, 'rb'),\n", + "\tkeep_fields = ['id','wiki_id'],\n", + "\tdataset_type=\"embed-input\"\n", + "\t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "3lAS4bcvCplJ", + "outputId": "5e1fcd0b-4880-43ed-d8a4-03148b2ef047" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "5NWR4MJUBQHW" - }, - "outputs": [], - "source": [ - "# Query the Database\n", - "query = \"What was the first youtube video about?\"\n", - "\n", - "# Convert the query into embeddings\n", - "query_emb=co.embed(\n", - " texts=[query], model=\"embed-english-v3.0\", input_type=\"search_query\"\n", - " ).embeddings\n", - "\n", - "# Retrieve the initial results from your vector db\n", - "doc_index = index.knn_query(query_emb, k=10)[0][0]\n", - "\n", - "# From the doc_index, get the text from each index and then pass the text into rerank\n", - "docs_to_rerank = []\n", - "for index in doc_index:\n", - " docs_to_rerank.append(texts[index])\n", - "\n", - "final_result = co.rerank(\n", - " query= query,\n", - " documents=docs_to_rerank,\n", - " model=\"rerank-english-v2.0\",\n", - " top_n=3)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "cohere.Dataset {\n", + "\tid: sample-file-hca4x0\n", + "\tname: sample_file\n", + "\tdataset_type: embed-input\n", + "\tvalidation_status: validated\n", + "\tcreated_at: 2024-01-13 02:51:48.215973\n", + "\tupdated_at: 2024-01-13 02:51:48.215973\n", + "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/f8bd5ab1-ccdf-45e6-9717-23b8be1ff39d/sample-file-hca4x0/000_embed_jobs_sample_data.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T025159Z&X-Goog-Expires=14399&X-Goog-Signature=7f9ed7cb27988e4bf447167160b25940cd106859d1282919604a0d74b882681b5aaa3245f97555bb61ddca7fd9c02fb0bba8391433c70aeb2118607dfd534db444097c5ae9c8d07e66bf6723a64634f5d6f5b2500c82e351807203f5fd3c278b2584c258b4c6afc6ee191e63bcd346e3dd2c7fd4b171c2d3ddfe8e6e68c2522111b6f63e125a052be9ebe3302903f4bef9cd165c8e075b168e621c7c61177a0973bb470cc3535457078e18b338884fb303792a1ba3161ab5ca5ce2adca5676754ee1a735891ccbf64cca03d3fdcabdcccd0d201600b8c70e13487bf897f2b88424cc736f8bf8756ec835b09dacf0aa20dc8151d9249b21d4ca4de82144fcd8be&X-Goog-SignedHeaders=host']\n", + "\tvalidation_error: None\n", + "\tvalidation_warnings: []\n", + "}\n" + ] + } + ], + "source": [ + "print(ds.await_validation())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgD2QCJk9kUN" + }, + "source": [ + "## Step 2: Create embeddings via Cohere's Embed Jobs endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "yMYoU9y55m2D", + "outputId": "fd58014d-a9e3-4a3f-ca4b-966880dec412" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "Oya4CRdE-WDU" - }, - "source": [ - "## Step 6: Display the results" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "...\n", + "...\n" + ] + } + ], + "source": [ + "# Dataset has been uploaded, create an embed job and specify the input type as \"search document\" since this will live in your Pinecone DB\n", + "job = co.create_embed_job(\n", + " dataset_id=ds.id,\n", + " input_type='search_document' ,\n", + " model='embed-english-v3.0', \n", + " embeddings_types=['float'])\n", + "\n", + "job.wait() # poll the server until the job is completed " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "LEevvN2XCUpR", + "outputId": "d123c0a4-0c6a-4235-9ba8-658d5d3ec358" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "rvs0Se2wER1a", - "outputId": "eeb3e148-af79-46c0-ca3b-ae9facde5fbc" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Document Rank: 1, Document Index: 0\n", - "Document: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", - "Relevance Score: 0.94815\n", - "\n", - "\n", - "Document Rank: 2, Document Index: 1\n", - "Document: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", - "Relevance Score: 0.91626\n", - "\n", - "\n", - "Document Rank: 3, Document Index: 2\n", - "Document: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n", - "Relevance Score: 0.90665\n", - "\n", - "\n" - ] - } - ], - "source": [ - "# Output Results\n", - "for idx, r in enumerate(final_result):\n", - " print(f\"Document Rank: {idx + 1}, Document Index: {r.index}\")\n", - " print(f\"Document: {r.document['text']}\")\n", - " print(f\"Relevance Score: {r.relevance_score:.5f}\")\n", - " print(\"\\n\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "cohere.EmbedJob {\n", + "\tjob_id: 792bbc1a-561b-48c2-8a97-0c80c1914ea8\n", + "\tstatus: complete\n", + "\tcreated_at: 2024-01-13T02:53:31.879719Z\n", + "\tinput_dataset_id: sample-file-hca4x0\n", + "\toutput_urls: None\n", + "\tmodel: embed-english-v3.0\n", + "\ttruncate: RIGHT\n", + "\tpercent_complete: 100\n", + "\toutput: cohere.Dataset {\n", + "\tid: embeded-sample-file-drtjf9\n", + "\tname: embeded-sample-file\n", + "\tdataset_type: embed-result\n", + "\tvalidation_status: validated\n", + "\tcreated_at: 2024-01-13 02:53:33.569362\n", + "\tupdated_at: 2024-01-13 02:53:33.569362\n", + "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/f8bd5ab1-ccdf-45e6-9717-23b8be1ff39d/embeded-sample-file-drtjf9/001_embeded-sample-file.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T025352Z&X-Goog-Expires=14399&X-Goog-Signature=927d2d73947058c95cd73f813e87e81416163dd0ccba1d5ce064a186fdc732550a605ff2122c9087fcc8e16dded9836084be532dac59622f73cb625fa1014fa9b1f9b702ca02be50006d8e2b2239870e3c765f7f8bd4964ccc74f4d9cc28672cd22c0d47008b112bd787eaab19692a5d9d724899f6aac088facdbe6d3b9d74f929fa07e76126656a5b0635a9793d9e85e692ca2d1d40f406869a53aa2e7390570d67e602fc5ea1741686176ce857112d5d68dee1b2fc62a436cd244890ec7c5901941cb10b01c2c41d6eba67dc393370a7c47526a7272f1f70f880b5fea2f69cb4546a633440a538fad7b92fdeb28d98aec1680cafc89142053da915268ea039&X-Goog-SignedHeaders=host']\n", + "\tvalidation_error: None\n", + "\tvalidation_warnings: []\n", + "}\n", + "}\n" + ] } - ], - "metadata": { + ], + "source": [ + "print(job)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZVf1njJ4952G" + }, + "source": [ + "## Step 3: Download and prepare the embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0FdyxbcR5uci" + }, + "outputs": [], + "source": [ + "# Save down the output of the job\n", + "embeddings_file_path = 'embed_jobs_output.csv'\n", + "output_dataset=co.get_dataset(job.output.id)\n", + "output_dataset.save(filepath=embeddings_file_path, format=\"csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VvheIBdJ6FC_" + }, + "outputs": [], + "source": [ + "# Add the results\n", + "embeddings=[]\n", + "texts=[]\n", + "for record in output_dataset:\n", + " embeddings.append(record['embeddings']['float'])\n", + " texts.append(record['text'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-O-Yz8MS-DFz" + }, + "source": [ + "## Step 4: Initialize Hnwslib index and add embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_vGfX8aQ9uD1" + }, + "outputs": [], + "source": [ + "# Create the hnsw index\n", + "index = hnswlib.Index(space='ip', dim=1024)\n", + "index.init_index(max_elements=len(embeddings), ef_construction=512, M=64)\n", + "index.add_items(embeddings,list(range(len(embeddings))))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yN5qBoVX-M7g" + }, + "source": [ + "## Step 5: Query the index and rerank the results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5NWR4MJUBQHW" + }, + "outputs": [], + "source": [ + "# Query the Database\n", + "query = \"What was the first youtube video about?\"\n", + "\n", + "# Convert the query into embeddings\n", + "query_emb=co.embed(\n", + " texts=[query], model=\"embed-english-v3.0\", input_type=\"search_query\"\n", + " ).embeddings\n", + "\n", + "# Retrieve the initial results from your vector db\n", + "doc_index = index.knn_query(query_emb, k=10)[0][0]\n", + "\n", + "# From the doc_index, get the text from each index and then pass the text into rerank\n", + "docs_to_rerank = []\n", + "for index in doc_index:\n", + " docs_to_rerank.append(texts[index])\n", + "\n", + "final_result = co.rerank(\n", + " query= query,\n", + " documents=docs_to_rerank,\n", + " model=\"rerank-english-v2.0\",\n", + " top_n=3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Oya4CRdE-WDU" + }, + "source": [ + "## Step 6: Display the results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "provenance": [] + "base_uri": "https://localhost:8080/" }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "name": "python" + "id": "rvs0Se2wER1a", + "outputId": "eeb3e148-af79-46c0-ca3b-ae9facde5fbc" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Document Rank: 1, Document Index: 0\n", + "Document: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", + "Relevance Score: 0.94815\n", + "\n", + "\n", + "Document Rank: 2, Document Index: 1\n", + "Document: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", + "Relevance Score: 0.91626\n", + "\n", + "\n", + "Document Rank: 3, Document Index: 2\n", + "Document: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n", + "Relevance Score: 0.90665\n", + "\n", + "\n" + ] } + ], + "source": [ + "# Output Results\n", + "for idx, r in enumerate(final_result):\n", + " print(f\"Document Rank: {idx + 1}, Document Index: {r.index}\")\n", + " print(f\"Document: {r.document['text']}\")\n", + " print(f\"Relevance Score: {r.relevance_score:.5f}\")\n", + " print(\"\\n\")" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/Embed_Jobs_Serverless_Pinecone_Semantic_Search.ipynb b/notebooks/Embed_Jobs_Serverless_Pinecone_Semantic_Search.ipynb index 4a3ff53b..d85f2c44 100644 --- a/notebooks/Embed_Jobs_Serverless_Pinecone_Semantic_Search.ipynb +++ b/notebooks/Embed_Jobs_Serverless_Pinecone_Semantic_Search.ipynb @@ -1,564 +1,561 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "frQ5it0RmB0_" - }, - "source": [ - "# Semantic Search with Cohere Embed Jobs and Pinecone serverless Solution" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Fdhi1O4lrqaV" - }, - "outputs": [], - "source": [ - "# TODO: upgrade to \"cohere>5\"\n", - "! pip install \"cohere<5\" \"pinecone-client>3.2.1\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "N_bYWQORGuMM", - "outputId": "ee9f81f3-e896-46ff-e287-48502cff0b29" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.10/dist-packages/pinecone/data/index.py:1: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", - " from tqdm.autonotebook import tqdm\n" - ] - } - ], - "source": [ - "import os\n", - "import json\n", - "import time\n", - "import numpy as np\n", - "import cohere\n", - "from pinecone import Pinecone\n", - "\n", - "co = cohere.Client('COHERE_API_KEY')\n", - "pc = Pinecone(\n", - " api_key=\"PINECONE_API_KEY\", \n", - " source_tag=\"cohere\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "XulUR7tt69RM" - }, - "source": [ - "## Step 1: Upload a dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "G677sKZc6NDv", - "outputId": "e4bfd9ca-590a-4cf7-d9cf-3657a16e2a7f" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "uploading file, starting validation...\n", - "sample-file-2gwgxq was uploaded\n", - "...\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cohere.Dataset {\n", - "\tid: sample-file-2gwgxq\n", - "\tname: sample_file\n", - "\tdataset_type: embed-input\n", - "\tvalidation_status: validated\n", - "\tcreated_at: 2024-01-13 02:47:32.563080\n", - "\tupdated_at: 2024-01-13 02:47:32.563081\n", - "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/96d12a16-2dd4-46f7-9630-1fa9bb0b26ca/sample-file-2gwgxq/000_embed_jobs_sample_data.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T024743Z&X-Goog-Expires=14399&X-Goog-Signature=1cc013824d54e4974600e19ec5c5dd6624c3de0c512f1c7d204fa95056b09e19d90c0fe034c59f0eef8bdfd4e1ed03b44c601d290e9b9c9e0643afd7a44fe97c42750304a8f199c9d87abb50fc74d777ab2d36efecca64ad97264f9e0628f2e199b9eb2d505241480a7436191cacaa78efb328567c9303469b653962caf07e6b11fac06ed06bd4597377e87fac58214bab1cd5cde63e19508d903e65ad654a177e27a64105b79c56d0cc156a35b61d45a7dda3b9819ef78dc9861c818b808527a1e16210dc83130be630f1b54c75d280ea20d070566056a6b2c7b1a016409482defc2a1942a801e46f5349adfadb244711da80d103ed831d6927366adc0c1659&X-Goog-SignedHeaders=host']\n", - "\tvalidation_error: None\n", - "\tvalidation_warnings: []\n", - "}\n" - ] - } - ], - "source": [ - "# Upload a dataset for embed jobs\n", - "dataset_file_path = \"data/embed_jobs_sample_data.jsonl\" # Full path - https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/embed_jobs_sample_data.jsonl\n", - "\n", - "ds=co.create_dataset(\n", - "\tname='sample_file',\n", - "\t# insert your file path here - you can upload it on the right - we accept .csv and jsonl files\n", - "\tdata=open(dataset_file_path, 'rb'),\n", - "\tdataset_type=\"embed-input\"\n", - "\t)\n", - "\n", - "print(ds.await_validation())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "5VAoaVo47Bmi" - }, - "source": [ - "## Step 2: Create embeddings via Cohere's Embed Jobs endpoint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "77Vw5BdWGzFl", - "outputId": "a5e0c9f5-8172-4b80-a8ea-aa4e763fdeda" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "...\n", - "...\n" - ] - } - ], - "source": [ - "# Dataset has been uploaded, create an embed job and specify the input type as \"search document\" since this will live in your Pinecone DB\n", - "job = co.create_embed_job(dataset_id=ds.id,\n", - " input_type='search_document',\n", - " model='embed-english-v3.0',\n", - " embeddings_types=['float'])\n", - "\n", - "job.wait() # poll the server until the job is completed " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "d__jANfVvNld", - "outputId": "c4dcd936-c338-47b3-994d-71cdceaa6796" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cohere.EmbedJob {\n", - "\tjob_id: 6d691fbe-e026-436a-826a-16e70b293e51\n", - "\tstatus: complete\n", - "\tcreated_at: 2024-01-13T02:47:46.385016Z\n", - "\tinput_dataset_id: sample-file-2gwgxq\n", - "\toutput_urls: None\n", - "\tmodel: embed-english-v3.0\n", - "\ttruncate: RIGHT\n", - "\tpercent_complete: 100\n", - "\toutput: cohere.Dataset {\n", - "\tid: embeded-sample-file-mdse2h\n", - "\tname: embeded-sample-file\n", - "\tdataset_type: embed-result\n", - "\tvalidation_status: validated\n", - "\tcreated_at: 2024-01-13 02:47:47.850097\n", - "\tupdated_at: 2024-01-13 02:47:47.850097\n", - "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/96d12a16-2dd4-46f7-9630-1fa9bb0b26ca/embeded-sample-file-mdse2h/001_embeded-sample-file.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T024807Z&X-Goog-Expires=14399&X-Goog-Signature=78b0d82e19388aee2926a4ef403d5f286487d0e7fc9a09c75bfb6700b502fa4f55b024977c0aeae26cd501a41e506bf00d3e850d7d9691298963374f04fa129e8dae5a327389c80921bf611a25386f5e4501b11c9d88bc1aee6f6877157a4675c5f8fe06bb25e3ca2b12da46e5b1da3067ca71bed901cd14db26e09987e355c039f96d6514a0931aa5f8753ddc155ca1782c63e3cb000b095d3b29904982ff75686c716329e92b6946485c567dabc3e344c9a0f9a59416415738b67ead0cca3cdb06c1db64c925ea38a2d92ab4079577e5775367260c09916aab5af67326bca4fa1295ee76457f933a6ca26a5d4ac9c59f0f73286627b2bae3e7fa7375c97465&X-Goog-SignedHeaders=host']\n", - "\tvalidation_error: None\n", - "\tvalidation_warnings: []\n", - "}\n", - "}\n" - ] - } - ], - "source": [ - "print(job)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "UlEVKOCG7ZsN" - }, - "source": [ - "## Step 3: Prepare embeddings for upsert" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "vDvntjsnG_DX" - }, - "outputs": [], - "source": [ - "# Load the output file into an array\n", - "output_dataset=co.get_dataset(job.output.id)\n", - "data_array = []\n", - "for record in output_dataset:\n", - " data_array.append(record)\n", - "\n", - "# Take the output and format it in the shape for upserting into Pinecone's DB\n", - "ids = [str(i) for i in range(len(data_array))]\n", - "meta = [{'text':str(data_array[i]['text'])} for i in range(len(data_array))]\n", - "embeds=[np.float32(data_array[i]['embeddings']['float']) for i in range(len(data_array))]\n", - "\n", - "to_upsert = list(zip(ids, embeds, meta))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "pQwXK4xt7lls" - }, - "source": [ - "## Step 4: Initialize Pinecone vector database" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "GrLN8Y_THEBH" - }, - "outputs": [], - "source": [ - "# Initialize your Pinecone Vector DB\n", - "from pinecone import ServerlessSpec\n", - "\n", - "index_name = \"embed-jobs-serverless-test-example\"\n", - "\n", - "# A new property 'spec' is used to tell Pinecone how we should deploy your index.\n", - "pc.create_index(\n", - "name=index_name,\n", - "dimension=1024,\n", - "metric=\"cosine\",\n", - "spec=ServerlessSpec(cloud='aws', region='us-west-2')\n", - ")\n", - "\n", - "# Target your new serverless index.\n", - "idx = pc.Index(index_name)" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "frQ5it0RmB0_" + }, + "source": [ + "# Semantic Search with Cohere Embed Jobs and Pinecone serverless Solution" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "N_bYWQORGuMM", + "outputId": "ee9f81f3-e896-46ff-e287-48502cff0b29" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "W2QMVhoM7o-5" - }, - "source": [ - "## Step 5: Upsert embeddings into the index" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.10/dist-packages/pinecone/data/index.py:1: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm\n" + ] + } + ], + "source": [ + "import os\n", + "import json\n", + "import time\n", + "import numpy as np\n", + "import cohere\n", + "from pinecone import Pinecone\n", + "\n", + "co = cohere.Client('COHERE_API_KEY')\n", + "pc = Pinecone(\n", + " api_key=\"PINECONE_API_KEY\", \n", + " source_tag=\"cohere\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XulUR7tt69RM" + }, + "source": [ + "## Step 1: Upload a dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "G677sKZc6NDv", + "outputId": "e4bfd9ca-590a-4cf7-d9cf-3657a16e2a7f" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "JaVrXHZ3IjiN", - "outputId": "716ad587-2ee1-475a-f1e5-9a0b23d2df87" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'dimension': 1024,\n", - " 'index_fullness': 0.0,\n", - " 'namespaces': {'': {'vector_count': 3664}},\n", - " 'total_vector_count': 3664}\n" - ] - } - ], - "source": [ - "# Upsert your data into the index\n", - "batch_size = 128\n", - "\n", - "for i in range(0, len(data_array), batch_size):\n", - " i_end = min(i+batch_size, len(data_array))\n", - " idx.upsert(vectors=to_upsert[i:i_end])\n", - "\n", - "# let's view the index statistics\n", - "print(idx.describe_index_stats())" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "uploading file, starting validation...\n", + "sample-file-2gwgxq was uploaded\n", + "...\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "AtT1Yo_i8CZc" - }, - "source": [ - "## Step 6: Query the index" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "cohere.Dataset {\n", + "\tid: sample-file-2gwgxq\n", + "\tname: sample_file\n", + "\tdataset_type: embed-input\n", + "\tvalidation_status: validated\n", + "\tcreated_at: 2024-01-13 02:47:32.563080\n", + "\tupdated_at: 2024-01-13 02:47:32.563081\n", + "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/96d12a16-2dd4-46f7-9630-1fa9bb0b26ca/sample-file-2gwgxq/000_embed_jobs_sample_data.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T024743Z&X-Goog-Expires=14399&X-Goog-Signature=1cc013824d54e4974600e19ec5c5dd6624c3de0c512f1c7d204fa95056b09e19d90c0fe034c59f0eef8bdfd4e1ed03b44c601d290e9b9c9e0643afd7a44fe97c42750304a8f199c9d87abb50fc74d777ab2d36efecca64ad97264f9e0628f2e199b9eb2d505241480a7436191cacaa78efb328567c9303469b653962caf07e6b11fac06ed06bd4597377e87fac58214bab1cd5cde63e19508d903e65ad654a177e27a64105b79c56d0cc156a35b61d45a7dda3b9819ef78dc9861c818b808527a1e16210dc83130be630f1b54c75d280ea20d070566056a6b2c7b1a016409482defc2a1942a801e46f5349adfadb244711da80d103ed831d6927366adc0c1659&X-Goog-SignedHeaders=host']\n", + "\tvalidation_error: None\n", + "\tvalidation_warnings: []\n", + "}\n" + ] + } + ], + "source": [ + "# Upload a dataset for embed jobs\n", + "dataset_file_path = \"data/embed_jobs_sample_data.jsonl\" # Full path - https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/embed_jobs_sample_data.jsonl\n", + "\n", + "ds=co.create_dataset(\n", + "\tname='sample_file',\n", + "\t# insert your file path here - you can upload it on the right - we accept .csv and jsonl files\n", + "\tdata=open(dataset_file_path, 'rb'),\n", + "\tdataset_type=\"embed-input\"\n", + "\t)\n", + "\n", + "print(ds.await_validation())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5VAoaVo47Bmi" + }, + "source": [ + "## Step 2: Create embeddings via Cohere's Embed Jobs endpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "77Vw5BdWGzFl", + "outputId": "a5e0c9f5-8172-4b80-a8ea-aa4e763fdeda" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "t-A82Z1EIrKR", - "outputId": "ed708eef-0c0b-4688-f0d7-f5fc39219848" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1, 1024)\n" - ] - } - ], - "source": [ - "# Let's query the database\n", - "query = \"What did Microsoft announce in Las Vegas?\"\n", - "\n", - "# create the query embedding\n", - "xq = co.embed(\n", - " texts=[query],\n", - " model='embed-english-v3.0',\n", - " input_type='search_query',\n", - " truncate='END'\n", - ").embeddings\n", - "\n", - "print(np.array(xq).shape)\n", - "\n", - "# query, returning the top 20 most similar results\n", - "res = idx.query(xq, top_k=20, include_metadata=True)" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "...\n", + "...\n" + ] + } + ], + "source": [ + "# Dataset has been uploaded, create an embed job and specify the input type as \"search document\" since this will live in your Pinecone DB\n", + "job = co.create_embed_job(dataset_id=ds.id,\n", + " input_type='search_document',\n", + " model='embed-english-v3.0',\n", + " embeddings_types=['float'])\n", + "\n", + "job.wait() # poll the server until the job is completed " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "d__jANfVvNld", + "outputId": "c4dcd936-c338-47b3-994d-71cdceaa6796" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "pXhvxHwj5nX2", - "outputId": "422948e1-a554-4bd2-9d28-076df6f5c3ee" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.48: On October 22, 2012, Microsoft announced the release of new features including co-authoring, performance improvements and touch support.\n", - "0.45: On May 2, 2019, at F8, the company announced its new vision with the tagline \"the future is private\". A redesign of the website and mobile app was introduced, dubbed as \"FB5\". The event also featured plans for improving groups, a dating platform, end-to-end encryption on its platforms, and allowing users on Messenger to communicate directly with WhatsApp and Instagram users.\n", - "0.42: On July 13, 2009, Microsoft announced at its Worldwide Partners Conference 2009 in New Orleans that Microsoft Office 2010 reached its \"Technical Preview\" development milestone and features of Office Web Apps were demonstrated to the public for the first time. Additionally, Microsoft announced that Office Web Apps would be made available to consumers online and free of charge, while Microsoft Software Assurance customers will have the option of running them on premises. Office 2010 beta testers were not given access to Office Web Apps at this date, and it was announced that it would be available for testers during August 2009. However, in August 2009, a Microsoft spokesperson stated that there had been a delay in the release of Office Web Apps Technical Preview and it would not be available by the end of August.\n", - "0.42: On January 17, 2017, Facebook COO Sheryl Sandberg planned to open Station F, a startup incubator campus in Paris, France. On a six-month cycle, Facebook committed to work with ten to 15 data-driven startups there. On April 18, Facebook announced the beta launch of at its annual F8 developer conference. Facebook Spaces is a virtual reality version of Facebook for Oculus VR goggles. In a virtual and shared space, users can access a curated selection of 360-degree photos and videos using their avatar, with the support of the controller. Users can access their own photos and videos, along with media shared on their newsfeed. In September, Facebook announced it would spend up to US$1 billion on original shows for its Facebook Watch platform. On October 16, it acquired the anonymous compliment app tbh, announcing its intention to leave the app independent.\n", - "0.41: On September 26, 2017, Microsoft announced that the next version of the suite for Windows desktop, Office 2019, was in development. On April 27, 2018, Microsoft released Office 2019 Commercial Preview for Windows 10. It was released to general availability for Windows 10 and for macOS on September 24, 2018.\n", - "0.41: Microsoft Office, or simply Office, is the former name of a family of client software, server software, and services developed by Microsoft. It was first announced by Bill Gates on August 1, 1988, at COMDEX in Las Vegas. Initially a marketing term for an office suite (bundled set of productivity applications), the first version of Office contained Microsoft Word, Microsoft Excel, and Microsoft PowerPoint. Over the years, Office applications have grown substantially closer with shared features such as a common spell checker, Object Linking and Embedding data integration and Visual Basic for Applications scripting language. Microsoft also positions Office as a development platform for line-of-business software under the Office Business Applications brand.\n", - "0.40: On August 12, 2009, it was announced that Office Mobile would also be released for the Symbian platform as a joint agreement between Microsoft and Nokia. It was the first time Microsoft would develop Office mobile applications for another smartphone platform. The first application to appear on Nokia Eseries smartphones was Microsoft Office Communicator. In February 2012, Microsoft released OneNote, Lync 2010, Document Connection and PowerPoint Broadcast for Symbian. In April, Word Mobile, PowerPoint Mobile and Excel Mobile joined the Office Suite.\n", - "0.40: In 2010, Microsoft introduced a software as a service platform known as Office 365, to provide cloud-hosted versions of Office's server software, including Exchange e-mail and SharePoint, on a subscription basis (competing in particular with Google Apps). Following the release of Office 2013, Microsoft began to offer Office 365 plans for the consumer market, with access to Microsoft Office software on multiple devices with free feature updates over the life of the subscription, as well as other services such as OneDrive storage.\n", - "0.40: On April 12, 2016, Zuckerberg outlined his 10-year vision, which rested on three main pillars: artificial intelligence, increased global connectivity, and virtual and augmented reality. In July, a suit was filed against the company alleging that it permitted Hamas to use it to perform assaults that cost the lives of four people. Facebook released its blueprints of Surround 360 camera on GitHub under an open-source license. In September, it won an Emmy for its animated short \"Henry\". In October, Facebook announced a fee-based communications tool called Workplace that aims to \"connect everyone\" at work. Users can create profiles, see updates from co-workers on their news feed, stream live videos and participate in secure group chats.\n", - "0.40: On January 22, 2015, the Microsoft Office blog announced that the next version of the suite for Windows desktop, Office 2016, was in development. On May 4, 2015, a public preview of Microsoft Office 2016 was released. Office 2016 was released for Mac OS X on July 9, 2015 and for Windows on September 22, 2015.\n", - "0.39: On November 6, 2013, Microsoft announced further new features including \"real-time\" co-authoring and an Auto-Save feature in Word (replacing the save button).\n", - "0.39: In February 2014, Office Web Apps were re-branded Office Online and incorporated into other Microsoft web services, including Calendar, OneDrive, Outlook.com, and People. Microsoft had previously attempted to unify its online services suite (including Microsoft Passport, Hotmail, MSN Messenger, and later SkyDrive) under a brand known as Windows Live, first launched in 2005. However, with the impending launch of Windows 8 and its increased use of cloud services, Microsoft dropped the Windows Live brand to emphasize that these services would now be built directly into Windows and not merely be a \"bolted on\" add-on. Critics had criticized the Windows Live brand for having no clear vision, as it was being applied to an increasingly broad array of unrelated services. At the same time, Windows Live Hotmail was re-launched as Outlook.com (sharing its name with the Microsoft Outlook personal information manager).\n", - "0.39: On February 18, 2021, Microsoft announced that the next version of the suite for Windows desktop, Office 2021, was in development. This new version will be supported for five years and was released on October 5, 2021.\n", - "0.38: Since Office 2013, Microsoft has promoted Office 365 as the primary means of obtaining Microsoft Office: it allows the use of the software and other services on a subscription business model, and users receive feature updates to the software for the lifetime of the subscription, including new features and cloud computing integration that are not necessarily included in the \"on-premises\" releases of Office sold under conventional license terms. In 2017, revenue from Office 365 overtook conventional license sales. Microsoft also rebranded most of their standard Office 365 editions as \"Microsoft 365\" to reflect their inclusion of features and services beyond the core Microsoft Office suite.\n", - "0.38: Microsoft has since promoted Office 365 as the primary means of purchasing Microsoft Office. Although there are still \"on-premises\" releases roughly every three years, Microsoft marketing emphasizes that they do not receive new features or access to new cloud-based services as they are released unlike Office 365, as well as other benefits for consumer and business markets. Office 365 revenue overtook traditional license sales for Office in 2017.\n", - "0.38: A technical preview of Microsoft Office 2013 (Build 15.0.3612.1010) was released on January 30, 2012, and a Customer Preview version was made available to consumers on July 16, 2012. It sports a revamped application interface; the interface is based on Metro, the interface of Windows Phone and Windows 8. Microsoft Outlook has received the most pronounced changes so far; for example, the Metro interface provides a new visualization for scheduled tasks. PowerPoint includes more templates and transition effects, and OneNote includes a new splash screen.\n", - "0.38: On January 21, 2015, during the \"Windows 10: The Next Chapter\" press event, Microsoft unveiled Office for Windows 10, Windows Runtime ports of the Android and iOS versions of the Office Mobile suite. Optimized for smartphones and tablets, they are universal apps that can run on both Windows and Windows for phones, and share similar underlying code. A simplified version of Outlook was also added to the suite. They will be bundled with Windows 10 mobile devices, and available from the Windows Store for the PC version of Windows 10. Although the preview versions were free for most editing, the release versions will require an Office 365 subscription on larger tablets (screen size larger than 10.1 inches) and desktops for editing, as with large Android tablets. Smaller tablets and phones will have most editing features for free.\n", - "0.38: In May 2018 at F8, the company announced it would offer its own dating service. Shares in competitor Match Group fell by 22%. Facebook Dating includes privacy features and friends are unable to view their friends' dating profile. In July, Facebook was charged £500,000 by UK watchdogs for failing to respond to data erasure requests. On July 18, Facebook established a subsidiary named Lianshu Science & Technology in Hangzhou City, China, with $30 million ($ in dollars) of capital. All its shares are held by Facebook Hong. Approval of the registration of the subsidiary was then withdrawn, due to a disagreement between officials in Zhejiang province and the Cyberspace Administration of China. On July 26, Facebook became the first company to lose over $100 billion ($ in dollars) worth of market capitalization in one day, dropping from nearly $630 billion to $510 billion after disappointing sales reports. On July 31, Facebook said that the company had deleted 17 accounts related to the 2018 U.S. midterm elections. On September 19, Facebook announced that, for news distribution outside the United States, it would work with U.S. funded democracy promotion organizations, International Republican Institute and the National Democratic Institute, which are loosely affiliated with the Republican and Democratic parties. Through the Digital Forensic Research Lab Facebook partners with the Atlantic Council, a NATO-affiliated think tank. In November, Facebook launched smart displays branded Portal and Portal Plus (Portal+). They support Amazon's Alexa (intelligent personal assistant service). The devices include video chat function with Facebook Messenger.\n", - "0.37: The first Preview version of Microsoft Office 2016 for Mac was released on March 5, 2015. On July 9, 2015, Microsoft released the final version of Microsoft Office 2016 for Mac which includes Word, Excel, PowerPoint, Outlook and OneNote. It was immediately made available for Office 365 subscribers with either a Home, Personal, Business, Business Premium, E3 or ProPlus subscription. A non–Office 365 edition of Office 2016 was made available as a one-time purchase option on September 22, 2015.\n", - "0.37: In October 2022, Microsoft announced that it will phase out the Microsoft Office brand in favor of \"Microsoft 365\" by January 2023. The name will continue to be used for legacy product offerings.\n" - ] - } - ], - "source": [ - "# Look at the initial retrieval results\n", - "for match in res['matches']:\n", - " print(f\"{match['score']:.2f}: {match['metadata']['text']}\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "cohere.EmbedJob {\n", + "\tjob_id: 6d691fbe-e026-436a-826a-16e70b293e51\n", + "\tstatus: complete\n", + "\tcreated_at: 2024-01-13T02:47:46.385016Z\n", + "\tinput_dataset_id: sample-file-2gwgxq\n", + "\toutput_urls: None\n", + "\tmodel: embed-english-v3.0\n", + "\ttruncate: RIGHT\n", + "\tpercent_complete: 100\n", + "\toutput: cohere.Dataset {\n", + "\tid: embeded-sample-file-mdse2h\n", + "\tname: embeded-sample-file\n", + "\tdataset_type: embed-result\n", + "\tvalidation_status: validated\n", + "\tcreated_at: 2024-01-13 02:47:47.850097\n", + "\tupdated_at: 2024-01-13 02:47:47.850097\n", + "\tdownload_urls: ['https://storage.googleapis.com/cohere-user/dataset-api-temp/d489c39a-e152-49da-9ddc-9801bd74d823/96d12a16-2dd4-46f7-9630-1fa9bb0b26ca/embeded-sample-file-mdse2h/001_embeded-sample-file.avro?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dataset%40cohere-production.iam.gserviceaccount.com%2F20240113%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240113T024807Z&X-Goog-Expires=14399&X-Goog-Signature=78b0d82e19388aee2926a4ef403d5f286487d0e7fc9a09c75bfb6700b502fa4f55b024977c0aeae26cd501a41e506bf00d3e850d7d9691298963374f04fa129e8dae5a327389c80921bf611a25386f5e4501b11c9d88bc1aee6f6877157a4675c5f8fe06bb25e3ca2b12da46e5b1da3067ca71bed901cd14db26e09987e355c039f96d6514a0931aa5f8753ddc155ca1782c63e3cb000b095d3b29904982ff75686c716329e92b6946485c567dabc3e344c9a0f9a59416415738b67ead0cca3cdb06c1db64c925ea38a2d92ab4079577e5775367260c09916aab5af67326bca4fa1295ee76457f933a6ca26a5d4ac9c59f0f73286627b2bae3e7fa7375c97465&X-Goog-SignedHeaders=host']\n", + "\tvalidation_error: None\n", + "\tvalidation_warnings: []\n", + "}\n", + "}\n" + ] + } + ], + "source": [ + "print(job)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UlEVKOCG7ZsN" + }, + "source": [ + "## Step 3: Prepare embeddings for upsert" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "vDvntjsnG_DX" + }, + "outputs": [], + "source": [ + "# Load the output file into an array\n", + "output_dataset=co.get_dataset(job.output.id)\n", + "data_array = []\n", + "for record in output_dataset:\n", + " data_array.append(record)\n", + "\n", + "# Take the output and format it in the shape for upserting into Pinecone's DB\n", + "ids = [str(i) for i in range(len(data_array))]\n", + "meta = [{'text':str(data_array[i]['text'])} for i in range(len(data_array))]\n", + "embeds=[np.float32(data_array[i]['embeddings']['float']) for i in range(len(data_array))]\n", + "\n", + "to_upsert = list(zip(ids, embeds, meta))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pQwXK4xt7lls" + }, + "source": [ + "## Step 4: Initialize Pinecone vector database" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "GrLN8Y_THEBH" + }, + "outputs": [], + "source": [ + "# Initialize your Pinecone Vector DB\n", + "from pinecone import ServerlessSpec\n", + "\n", + "index_name = \"embed-jobs-serverless-test-example\"\n", + "\n", + "# A new property 'spec' is used to tell Pinecone how we should deploy your index.\n", + "pc.create_index(\n", + "name=index_name,\n", + "dimension=1024,\n", + "metric=\"cosine\",\n", + "spec=ServerlessSpec(cloud='aws', region='us-west-2')\n", + ")\n", + "\n", + "# Target your new serverless index.\n", + "idx = pc.Index(index_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W2QMVhoM7o-5" + }, + "source": [ + "## Step 5: Upsert embeddings into the index" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "JaVrXHZ3IjiN", + "outputId": "716ad587-2ee1-475a-f1e5-9a0b23d2df87" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "DyevqtBB8KyU" - }, - "source": [ - "## Step 7: Rerank the retrieved results" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "{'dimension': 1024,\n", + " 'index_fullness': 0.0,\n", + " 'namespaces': {'': {'vector_count': 3664}},\n", + " 'total_vector_count': 3664}\n" + ] + } + ], + "source": [ + "# Upsert your data into the index\n", + "batch_size = 128\n", + "\n", + "for i in range(0, len(data_array), batch_size):\n", + " i_end = min(i+batch_size, len(data_array))\n", + " idx.upsert(vectors=to_upsert[i:i_end])\n", + "\n", + "# let's view the index statistics\n", + "print(idx.describe_index_stats())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AtT1Yo_i8CZc" + }, + "source": [ + "## Step 6: Query the index" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "t-A82Z1EIrKR", + "outputId": "ed708eef-0c0b-4688-f0d7-f5fc39219848" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "Rqo6YdzJI0ny", - "outputId": "aac1de9a-9cae-4c4c-f4a3-fb87583f62f2" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.99: Microsoft Office, or simply Office, is the former name of a family of client software, server software, and services developed by Microsoft. It was first announced by Bill Gates on August 1, 1988, at COMDEX in Las Vegas. Initially a marketing term for an office suite (bundled set of productivity applications), the first version of Office contained Microsoft Word, Microsoft Excel, and Microsoft PowerPoint. Over the years, Office applications have grown substantially closer with shared features such as a common spell checker, Object Linking and Embedding data integration and Visual Basic for Applications scripting language. Microsoft also positions Office as a development platform for line-of-business software under the Office Business Applications brand.\n", - "0.93: On January 21, 2015, during the \"Windows 10: The Next Chapter\" press event, Microsoft unveiled Office for Windows 10, Windows Runtime ports of the Android and iOS versions of the Office Mobile suite. Optimized for smartphones and tablets, they are universal apps that can run on both Windows and Windows for phones, and share similar underlying code. A simplified version of Outlook was also added to the suite. They will be bundled with Windows 10 mobile devices, and available from the Windows Store for the PC version of Windows 10. Although the preview versions were free for most editing, the release versions will require an Office 365 subscription on larger tablets (screen size larger than 10.1 inches) and desktops for editing, as with large Android tablets. Smaller tablets and phones will have most editing features for free.\n", - "0.87: In October 2022, Microsoft announced that it will phase out the Microsoft Office brand in favor of \"Microsoft 365\" by January 2023. The name will continue to be used for legacy product offerings.\n" - ] - } - ], - "source": [ - "# Add Cohere Reranking Step\n", - "docs =[match['metadata']['text'] for match in res['matches']]\n", - "\n", - "rerank_response = co.rerank(\n", - " model = 'rerank-english-v2.0',\n", - " query = query,\n", - " documents = docs,\n", - " top_n = 3,\n", - ")\n", - "for response in rerank_response:\n", - " print(f\"{response.relevance_score:.2f}: {response.document['text']}\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 1024)\n" + ] + } + ], + "source": [ + "# Let's query the database\n", + "query = \"What did Microsoft announce in Las Vegas?\"\n", + "\n", + "# create the query embedding\n", + "xq = co.embed(\n", + " texts=[query],\n", + " model='embed-english-v3.0',\n", + " input_type='search_query',\n", + " truncate='END'\n", + ").embeddings\n", + "\n", + "print(np.array(xq).shape)\n", + "\n", + "# query, returning the top 20 most similar results\n", + "res = idx.query(xq, top_k=20, include_metadata=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "pXhvxHwj5nX2", + "outputId": "422948e1-a554-4bd2-9d28-076df6f5c3ee" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Another example - query and rerank" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "0.48: On October 22, 2012, Microsoft announced the release of new features including co-authoring, performance improvements and touch support.\n", + "0.45: On May 2, 2019, at F8, the company announced its new vision with the tagline \"the future is private\". A redesign of the website and mobile app was introduced, dubbed as \"FB5\". The event also featured plans for improving groups, a dating platform, end-to-end encryption on its platforms, and allowing users on Messenger to communicate directly with WhatsApp and Instagram users.\n", + "0.42: On July 13, 2009, Microsoft announced at its Worldwide Partners Conference 2009 in New Orleans that Microsoft Office 2010 reached its \"Technical Preview\" development milestone and features of Office Web Apps were demonstrated to the public for the first time. Additionally, Microsoft announced that Office Web Apps would be made available to consumers online and free of charge, while Microsoft Software Assurance customers will have the option of running them on premises. Office 2010 beta testers were not given access to Office Web Apps at this date, and it was announced that it would be available for testers during August 2009. However, in August 2009, a Microsoft spokesperson stated that there had been a delay in the release of Office Web Apps Technical Preview and it would not be available by the end of August.\n", + "0.42: On January 17, 2017, Facebook COO Sheryl Sandberg planned to open Station F, a startup incubator campus in Paris, France. On a six-month cycle, Facebook committed to work with ten to 15 data-driven startups there. On April 18, Facebook announced the beta launch of at its annual F8 developer conference. Facebook Spaces is a virtual reality version of Facebook for Oculus VR goggles. In a virtual and shared space, users can access a curated selection of 360-degree photos and videos using their avatar, with the support of the controller. Users can access their own photos and videos, along with media shared on their newsfeed. In September, Facebook announced it would spend up to US$1 billion on original shows for its Facebook Watch platform. On October 16, it acquired the anonymous compliment app tbh, announcing its intention to leave the app independent.\n", + "0.41: On September 26, 2017, Microsoft announced that the next version of the suite for Windows desktop, Office 2019, was in development. On April 27, 2018, Microsoft released Office 2019 Commercial Preview for Windows 10. It was released to general availability for Windows 10 and for macOS on September 24, 2018.\n", + "0.41: Microsoft Office, or simply Office, is the former name of a family of client software, server software, and services developed by Microsoft. It was first announced by Bill Gates on August 1, 1988, at COMDEX in Las Vegas. Initially a marketing term for an office suite (bundled set of productivity applications), the first version of Office contained Microsoft Word, Microsoft Excel, and Microsoft PowerPoint. Over the years, Office applications have grown substantially closer with shared features such as a common spell checker, Object Linking and Embedding data integration and Visual Basic for Applications scripting language. Microsoft also positions Office as a development platform for line-of-business software under the Office Business Applications brand.\n", + "0.40: On August 12, 2009, it was announced that Office Mobile would also be released for the Symbian platform as a joint agreement between Microsoft and Nokia. It was the first time Microsoft would develop Office mobile applications for another smartphone platform. The first application to appear on Nokia Eseries smartphones was Microsoft Office Communicator. In February 2012, Microsoft released OneNote, Lync 2010, Document Connection and PowerPoint Broadcast for Symbian. In April, Word Mobile, PowerPoint Mobile and Excel Mobile joined the Office Suite.\n", + "0.40: In 2010, Microsoft introduced a software as a service platform known as Office 365, to provide cloud-hosted versions of Office's server software, including Exchange e-mail and SharePoint, on a subscription basis (competing in particular with Google Apps). Following the release of Office 2013, Microsoft began to offer Office 365 plans for the consumer market, with access to Microsoft Office software on multiple devices with free feature updates over the life of the subscription, as well as other services such as OneDrive storage.\n", + "0.40: On April 12, 2016, Zuckerberg outlined his 10-year vision, which rested on three main pillars: artificial intelligence, increased global connectivity, and virtual and augmented reality. In July, a suit was filed against the company alleging that it permitted Hamas to use it to perform assaults that cost the lives of four people. Facebook released its blueprints of Surround 360 camera on GitHub under an open-source license. In September, it won an Emmy for its animated short \"Henry\". In October, Facebook announced a fee-based communications tool called Workplace that aims to \"connect everyone\" at work. Users can create profiles, see updates from co-workers on their news feed, stream live videos and participate in secure group chats.\n", + "0.40: On January 22, 2015, the Microsoft Office blog announced that the next version of the suite for Windows desktop, Office 2016, was in development. On May 4, 2015, a public preview of Microsoft Office 2016 was released. Office 2016 was released for Mac OS X on July 9, 2015 and for Windows on September 22, 2015.\n", + "0.39: On November 6, 2013, Microsoft announced further new features including \"real-time\" co-authoring and an Auto-Save feature in Word (replacing the save button).\n", + "0.39: In February 2014, Office Web Apps were re-branded Office Online and incorporated into other Microsoft web services, including Calendar, OneDrive, Outlook.com, and People. Microsoft had previously attempted to unify its online services suite (including Microsoft Passport, Hotmail, MSN Messenger, and later SkyDrive) under a brand known as Windows Live, first launched in 2005. However, with the impending launch of Windows 8 and its increased use of cloud services, Microsoft dropped the Windows Live brand to emphasize that these services would now be built directly into Windows and not merely be a \"bolted on\" add-on. Critics had criticized the Windows Live brand for having no clear vision, as it was being applied to an increasingly broad array of unrelated services. At the same time, Windows Live Hotmail was re-launched as Outlook.com (sharing its name with the Microsoft Outlook personal information manager).\n", + "0.39: On February 18, 2021, Microsoft announced that the next version of the suite for Windows desktop, Office 2021, was in development. This new version will be supported for five years and was released on October 5, 2021.\n", + "0.38: Since Office 2013, Microsoft has promoted Office 365 as the primary means of obtaining Microsoft Office: it allows the use of the software and other services on a subscription business model, and users receive feature updates to the software for the lifetime of the subscription, including new features and cloud computing integration that are not necessarily included in the \"on-premises\" releases of Office sold under conventional license terms. In 2017, revenue from Office 365 overtook conventional license sales. Microsoft also rebranded most of their standard Office 365 editions as \"Microsoft 365\" to reflect their inclusion of features and services beyond the core Microsoft Office suite.\n", + "0.38: Microsoft has since promoted Office 365 as the primary means of purchasing Microsoft Office. Although there are still \"on-premises\" releases roughly every three years, Microsoft marketing emphasizes that they do not receive new features or access to new cloud-based services as they are released unlike Office 365, as well as other benefits for consumer and business markets. Office 365 revenue overtook traditional license sales for Office in 2017.\n", + "0.38: A technical preview of Microsoft Office 2013 (Build 15.0.3612.1010) was released on January 30, 2012, and a Customer Preview version was made available to consumers on July 16, 2012. It sports a revamped application interface; the interface is based on Metro, the interface of Windows Phone and Windows 8. Microsoft Outlook has received the most pronounced changes so far; for example, the Metro interface provides a new visualization for scheduled tasks. PowerPoint includes more templates and transition effects, and OneNote includes a new splash screen.\n", + "0.38: On January 21, 2015, during the \"Windows 10: The Next Chapter\" press event, Microsoft unveiled Office for Windows 10, Windows Runtime ports of the Android and iOS versions of the Office Mobile suite. Optimized for smartphones and tablets, they are universal apps that can run on both Windows and Windows for phones, and share similar underlying code. A simplified version of Outlook was also added to the suite. They will be bundled with Windows 10 mobile devices, and available from the Windows Store for the PC version of Windows 10. Although the preview versions were free for most editing, the release versions will require an Office 365 subscription on larger tablets (screen size larger than 10.1 inches) and desktops for editing, as with large Android tablets. Smaller tablets and phones will have most editing features for free.\n", + "0.38: In May 2018 at F8, the company announced it would offer its own dating service. Shares in competitor Match Group fell by 22%. Facebook Dating includes privacy features and friends are unable to view their friends' dating profile. In July, Facebook was charged £500,000 by UK watchdogs for failing to respond to data erasure requests. On July 18, Facebook established a subsidiary named Lianshu Science & Technology in Hangzhou City, China, with $30 million ($ in dollars) of capital. All its shares are held by Facebook Hong. Approval of the registration of the subsidiary was then withdrawn, due to a disagreement between officials in Zhejiang province and the Cyberspace Administration of China. On July 26, Facebook became the first company to lose over $100 billion ($ in dollars) worth of market capitalization in one day, dropping from nearly $630 billion to $510 billion after disappointing sales reports. On July 31, Facebook said that the company had deleted 17 accounts related to the 2018 U.S. midterm elections. On September 19, Facebook announced that, for news distribution outside the United States, it would work with U.S. funded democracy promotion organizations, International Republican Institute and the National Democratic Institute, which are loosely affiliated with the Republican and Democratic parties. Through the Digital Forensic Research Lab Facebook partners with the Atlantic Council, a NATO-affiliated think tank. In November, Facebook launched smart displays branded Portal and Portal Plus (Portal+). They support Amazon's Alexa (intelligent personal assistant service). The devices include video chat function with Facebook Messenger.\n", + "0.37: The first Preview version of Microsoft Office 2016 for Mac was released on March 5, 2015. On July 9, 2015, Microsoft released the final version of Microsoft Office 2016 for Mac which includes Word, Excel, PowerPoint, Outlook and OneNote. It was immediately made available for Office 365 subscribers with either a Home, Personal, Business, Business Premium, E3 or ProPlus subscription. A non–Office 365 edition of Office 2016 was made available as a one-time purchase option on September 22, 2015.\n", + "0.37: In October 2022, Microsoft announced that it will phase out the Microsoft Office brand in favor of \"Microsoft 365\" by January 2023. The name will continue to be used for legacy product offerings.\n" + ] + } + ], + "source": [ + "# Look at the initial retrieval results\n", + "for match in res['matches']:\n", + " print(f\"{match['score']:.2f}: {match['metadata']['text']}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyevqtBB8KyU" + }, + "source": [ + "## Step 7: Rerank the retrieved results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "Rqo6YdzJI0ny", + "outputId": "aac1de9a-9cae-4c4c-f4a3-fb87583f62f2" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "2laQ-A5x9HY8", - "outputId": "c3d831fd-5df7-412e-8637-9c51c51c0846" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1, 1024)\n", - "0.66: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", - "0.58: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", - "0.55: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n", - "0.55: According to a story that has often been repeated in the media, Hurley and Chen developed the idea for YouTube during the early months of 2005, after they had experienced difficulty sharing videos that had been shot at a dinner party at Chen's apartment in San Francisco. Karim did not attend the party and denied that it had occurred, but Chen remarked that the idea that YouTube was founded after a dinner party \"was probably very strengthened by marketing ideas around creating a story that was very digestible\".\n", - "0.53: In December 2009, YouTube partnered with Vevo. In April 2010, Lady Gaga's \"Bad Romance\" became the most viewed video, becoming the first video to reach 200 million views on May 9, 2010.\n", - "0.53: YouTube is a global online video sharing and social media platform headquartered in San Bruno, California. It was launched on February 14, 2005, by Steve Chen, Chad Hurley, and Jawed Karim. It is owned by Google, and is the second most visited website, after Google Search. YouTube has more than 2.5 billion monthly users who collectively watch more than one billion hours of videos each day. , videos were being uploaded at a rate of more than 500 hours of content per minute.\n", - "0.53: YouTube has faced numerous challenges and criticisms in its attempts to deal with copyright, including the site's first viral video, Lazy Sunday, which had to be taken down, due to copyright concerns. At the time of uploading a video, YouTube users are shown a message asking them not to violate copyright laws. Despite this advice, many unauthorized clips of copyrighted material remain on YouTube. YouTube does not view videos before they are posted online, and it is left to copyright holders to issue a DMCA takedown notice pursuant to the terms of the Online Copyright Infringement Liability Limitation Act. Any successful complaint about copyright infringement results in a YouTube copyright strike. Three successful complaints for copyright infringement against a user account will result in the account and all of its uploaded videos being deleted. From 2007 to 2009 organizations including Viacom, Mediaset, and the English Premier League have filed lawsuits against YouTube, claiming that it has done too little to prevent the uploading of copyrighted material.\n", - "0.51: Some YouTube videos have themselves had a direct effect on world events, such as \"Innocence of Muslims\" (2012) which spurred protests and related anti-American violence internationally. TED curator Chris Anderson described a phenomenon by which geographically distributed individuals in a certain field share their independently developed skills in YouTube videos, thus challenging others to improve their own skills, and spurring invention and evolution in that field. Journalist Virginia Heffernan stated in \"The New York Times\" that such videos have \"surprising implications\" for the dissemination of culture and even the future of classical music.\n", - "0.50: Observing that face-to-face communication of the type that online videos convey has been \"fine-tuned by millions of years of evolution,\" TED curator Chris Anderson referred to several YouTube contributors and asserted that \"what Gutenberg did for writing, online video can now do for face-to-face communication.\" Anderson asserted that it is not far-fetched to say that online video will dramatically accelerate scientific advance, and that video contributors may be about to launch \"the biggest learning cycle in human history.\" In education, for example, the Khan Academy grew from YouTube video tutoring sessions for founder Salman Khan's cousin into what \"Forbes\" Michael Noer called \"the largest school in the world,\" with technology poised to disrupt how people learn. YouTube was awarded a 2008 George Foster Peabody Award, the website being described as a Speakers' Corner that \"both embodies and promotes democracy.\" \"The Washington Post\" reported that a disproportionate share of YouTube's most subscribed channels feature minorities, contrasting with mainstream television in which the stars are largely white. A Pew Research Center study reported the development of \"visual journalism,\" in which citizen eyewitnesses and established news organizations share in content creation. The study also concluded that YouTube was becoming an important platform by which people acquire news.\n", - "0.50: YouTube was founded by Steve Chen, Chad Hurley, and Jawed Karim. The trio were early employees of PayPal, which left them enriched after the company was bought by eBay. Hurley had studied design at the Indiana University of Pennsylvania, and Chen and Karim studied computer science together at the University of Illinois Urbana-Champaign.\n", - "0.49: In 2013, YouTube teamed up with satirical newspaper company \"The Onion\" to claim in an uploaded video that the video-sharing website was launched as a contest which had finally come to an end, and would shut down for ten years before being re-launched in 2023, featuring only the winning video. The video starred several YouTube celebrities, including Antoine Dodson. A video of two presenters announcing the nominated videos streamed live for 12 hours.\n", - "0.48: Since its purchase by Google, YouTube has expanded beyond the core website into mobile apps, network television, and the ability to link with other platforms. Video categories on YouTube include music videos, video clips, news, short films, feature films, documentaries, audio recordings, movie trailers, teasers, live streams, vlogs, and more. Most content is generated by individuals, including collaborations between YouTubers and corporate sponsors. Established media corporations such as Disney, Paramount, and Warner Bros. Discovery have also created and expanded their corporate YouTube channels to advertise to a larger audience.\n", - "0.47: YouTube has enabled people to more directly engage with government, such as in the CNN/YouTube presidential debates (2007) in which ordinary people submitted questions to U.S. presidential candidates via YouTube video, with a techPresident co-founder saying that Internet video was changing the political landscape. Describing the Arab Spring (2010–2012), sociologist Philip N. Howard quoted an activist's succinct description that organizing the political unrest involved using \"Facebook to schedule the protests, Twitter to coordinate, and YouTube to tell the world.\" In 2012, more than a third of the U.S. Senate introduced a resolution condemning Joseph Kony 16 days after the \"Kony 2012\" video was posted to YouTube, with resolution co-sponsor Senator Lindsey Graham remarking that the video \"will do more to lead to (Kony's) demise than all other action combined.\"\n", - "0.47: YouTube carried out early experiments with live streaming, including a concert by U2 in 2009, and a question-and-answer session with US President Barack Obama in February 2010. These tests had relied on technology from 3rd-party partners, but in September 2010, YouTube began testing its own live streaming infrastructure. In April 2011, YouTube announced the rollout of \"YouTube Live\". The creation of live streams was initially limited to select partners. It was used for real-time broadcasting of events such as the 2012 Olympics in London. In October 2012, more than 8 million people watched Felix Baumgartner's jump from the edge of space as a live stream on YouTube.\n", - "0.46: In June 2007, YouTube began trials of a system for automatic detection of uploaded videos that infringe copyright. Google CEO Eric Schmidt regarded this system as necessary for resolving lawsuits such as the one from Viacom, which alleged that YouTube profited from content that it did not have the right to distribute. The system, which was initially called \"Video Identification\" and later became known as Content ID, creates an ID File for copyrighted audio and video material, and stores it in a database. When a video is uploaded, it is checked against the database, and flags the video as a copyright violation if a match is found. When this occurs, the content owner has the choice of blocking the video to make it unviewable, tracking the viewing statistics of the video, or adding advertisements to the video.\n", - "0.46: In January 2009, YouTube launched \"YouTube for TV\", a version of the website tailored for set-top boxes and other TV-based media devices with web browsers, initially allowing its videos to be viewed on the PlayStation 3 and Wii video game consoles.\n", - "0.46: In September 2012, YouTube launched its first app for the iPhone, following the decision to drop YouTube as one of the preloaded apps in the iPhone 5 and iOS 6 operating system. According to GlobalWebIndex, YouTube was used by 35% of smartphone users between April and June 2013, making it the third-most used app.\n", - "0.46: Conversely, YouTube has also allowed government to more easily engage with citizens, the White House's official YouTube channel being the seventh top news organization producer on YouTube in 2012 and in 2013 a healthcare exchange commissioned Obama impersonator Iman Crosson's YouTube music video spoof to encourage young Americans to enroll in the Affordable Care Act (Obamacare)-compliant health insurance. In February 2014, U.S. President Obama held a meeting at the White House with leading YouTube content creators to not only promote awareness of Obamacare but more generally to develop ways for government to better connect with the \"YouTube Generation.\" Whereas YouTube's inherent ability to allow presidents to directly connect with average citizens was noted, the YouTube content creators' new media savvy was perceived necessary to better cope with the website's distracting content and fickle audience.\n", - "0.46: Later that year, YouTube came under criticism for showing inappropriate videos targeted at children and often featuring popular characters in violent, sexual or otherwise disturbing situations, many of which appeared on YouTube Kids and attracted millions of views. The term \"Elsagate\" was coined on the Internet and then used by various news outlets to refer to this controversy. On November 11, 2017, YouTube announced it was strengthening site security to protect children from unsuitable content. Later that month, the company started to mass delete videos and channels that made improper use of family-friendly characters. As part of a broader concern regarding child safety on YouTube, the wave of deletions also targeted channels that showed children taking part in inappropriate or dangerous activities under the guidance of adults. Most notably, the company removed \"Toy Freaks\", a channel with over 8.5 million subscribers, that featured a father and his two daughters in odd and upsetting situations. According to analytics specialist SocialBlade, it earned up to £8.7 million annually prior to its deletion.\n", - "0.45: In September 2020, YouTube announced that it would be launching a beta version of a new platform of 15-second videos, similar to TikTok, called YouTube Shorts. The platform was first tested in India but as of March 2021 has expanded to other countries including the United States with videos now able to be up to 1 minute long. The platform is not a standalone app, but is integrated into the main YouTube app. Like TikTok, it gives users access to built-in creative tools, including the possibility of adding licensed music to their videos. The platform had its global beta launch in July 2021.\n" - ] - } - ], - "source": [ - "# Let's query the database\n", - "query = \"What was the first youtube video about?\"\n", - "\n", - "# create the query embedding\n", - "xq = co.embed(\n", - " texts=[query],\n", - " model='embed-english-v3.0',\n", - " input_type='search_query',\n", - " truncate='END'\n", - ").embeddings\n", - "\n", - "print(np.array(xq).shape)\n", - "\n", - "# query, returning the top 20 most similar results\n", - "res = idx.query(xq, top_k=20, include_metadata=True)\n", - "\n", - "# Look at the initial retrieval results\n", - "for match in res['matches']:\n", - " print(f\"{match['score']:.2f}: {match['metadata']['text']}\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "0.99: Microsoft Office, or simply Office, is the former name of a family of client software, server software, and services developed by Microsoft. It was first announced by Bill Gates on August 1, 1988, at COMDEX in Las Vegas. Initially a marketing term for an office suite (bundled set of productivity applications), the first version of Office contained Microsoft Word, Microsoft Excel, and Microsoft PowerPoint. Over the years, Office applications have grown substantially closer with shared features such as a common spell checker, Object Linking and Embedding data integration and Visual Basic for Applications scripting language. Microsoft also positions Office as a development platform for line-of-business software under the Office Business Applications brand.\n", + "0.93: On January 21, 2015, during the \"Windows 10: The Next Chapter\" press event, Microsoft unveiled Office for Windows 10, Windows Runtime ports of the Android and iOS versions of the Office Mobile suite. Optimized for smartphones and tablets, they are universal apps that can run on both Windows and Windows for phones, and share similar underlying code. A simplified version of Outlook was also added to the suite. They will be bundled with Windows 10 mobile devices, and available from the Windows Store for the PC version of Windows 10. Although the preview versions were free for most editing, the release versions will require an Office 365 subscription on larger tablets (screen size larger than 10.1 inches) and desktops for editing, as with large Android tablets. Smaller tablets and phones will have most editing features for free.\n", + "0.87: In October 2022, Microsoft announced that it will phase out the Microsoft Office brand in favor of \"Microsoft 365\" by January 2023. The name will continue to be used for legacy product offerings.\n" + ] + } + ], + "source": [ + "# Add Cohere Reranking Step\n", + "docs =[match['metadata']['text'] for match in res['matches']]\n", + "\n", + "rerank_response = co.rerank(\n", + " model = 'rerank-english-v2.0',\n", + " query = query,\n", + " documents = docs,\n", + " top_n = 3,\n", + ")\n", + "for response in rerank_response:\n", + " print(f\"{response.relevance_score:.2f}: {response.document['text']}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Another example - query and rerank" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "2laQ-A5x9HY8", + "outputId": "c3d831fd-5df7-412e-8637-9c51c51c0846" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "WaN6U6u19Md6", - "outputId": "9984d8ce-1383-4530-ec84-6e3f3feea05e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.95: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", - "0.92: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", - "0.91: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n" - ] - } - ], - "source": [ - "# Add Cohere Reranking Step\n", - "# embeds=[np.float32(data_array[i]['embedding']) for i in range(len(data_array))]\n", - "docs =[match['metadata']['text'] for match in res['matches']]\n", - "\n", - "rerank_response = co.rerank(\n", - " model = 'rerank-english-v2.0',\n", - " query = query,\n", - " documents = docs,\n", - " top_n = 3,\n", - ")\n", - "for response in rerank_response:\n", - " print(f\"{response.relevance_score:.2f}: {response.document['text']}\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 1024)\n", + "0.66: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", + "0.58: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", + "0.55: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n", + "0.55: According to a story that has often been repeated in the media, Hurley and Chen developed the idea for YouTube during the early months of 2005, after they had experienced difficulty sharing videos that had been shot at a dinner party at Chen's apartment in San Francisco. Karim did not attend the party and denied that it had occurred, but Chen remarked that the idea that YouTube was founded after a dinner party \"was probably very strengthened by marketing ideas around creating a story that was very digestible\".\n", + "0.53: In December 2009, YouTube partnered with Vevo. In April 2010, Lady Gaga's \"Bad Romance\" became the most viewed video, becoming the first video to reach 200 million views on May 9, 2010.\n", + "0.53: YouTube is a global online video sharing and social media platform headquartered in San Bruno, California. It was launched on February 14, 2005, by Steve Chen, Chad Hurley, and Jawed Karim. It is owned by Google, and is the second most visited website, after Google Search. YouTube has more than 2.5 billion monthly users who collectively watch more than one billion hours of videos each day. , videos were being uploaded at a rate of more than 500 hours of content per minute.\n", + "0.53: YouTube has faced numerous challenges and criticisms in its attempts to deal with copyright, including the site's first viral video, Lazy Sunday, which had to be taken down, due to copyright concerns. At the time of uploading a video, YouTube users are shown a message asking them not to violate copyright laws. Despite this advice, many unauthorized clips of copyrighted material remain on YouTube. YouTube does not view videos before they are posted online, and it is left to copyright holders to issue a DMCA takedown notice pursuant to the terms of the Online Copyright Infringement Liability Limitation Act. Any successful complaint about copyright infringement results in a YouTube copyright strike. Three successful complaints for copyright infringement against a user account will result in the account and all of its uploaded videos being deleted. From 2007 to 2009 organizations including Viacom, Mediaset, and the English Premier League have filed lawsuits against YouTube, claiming that it has done too little to prevent the uploading of copyrighted material.\n", + "0.51: Some YouTube videos have themselves had a direct effect on world events, such as \"Innocence of Muslims\" (2012) which spurred protests and related anti-American violence internationally. TED curator Chris Anderson described a phenomenon by which geographically distributed individuals in a certain field share their independently developed skills in YouTube videos, thus challenging others to improve their own skills, and spurring invention and evolution in that field. Journalist Virginia Heffernan stated in \"The New York Times\" that such videos have \"surprising implications\" for the dissemination of culture and even the future of classical music.\n", + "0.50: Observing that face-to-face communication of the type that online videos convey has been \"fine-tuned by millions of years of evolution,\" TED curator Chris Anderson referred to several YouTube contributors and asserted that \"what Gutenberg did for writing, online video can now do for face-to-face communication.\" Anderson asserted that it is not far-fetched to say that online video will dramatically accelerate scientific advance, and that video contributors may be about to launch \"the biggest learning cycle in human history.\" In education, for example, the Khan Academy grew from YouTube video tutoring sessions for founder Salman Khan's cousin into what \"Forbes\" Michael Noer called \"the largest school in the world,\" with technology poised to disrupt how people learn. YouTube was awarded a 2008 George Foster Peabody Award, the website being described as a Speakers' Corner that \"both embodies and promotes democracy.\" \"The Washington Post\" reported that a disproportionate share of YouTube's most subscribed channels feature minorities, contrasting with mainstream television in which the stars are largely white. A Pew Research Center study reported the development of \"visual journalism,\" in which citizen eyewitnesses and established news organizations share in content creation. The study also concluded that YouTube was becoming an important platform by which people acquire news.\n", + "0.50: YouTube was founded by Steve Chen, Chad Hurley, and Jawed Karim. The trio were early employees of PayPal, which left them enriched after the company was bought by eBay. Hurley had studied design at the Indiana University of Pennsylvania, and Chen and Karim studied computer science together at the University of Illinois Urbana-Champaign.\n", + "0.49: In 2013, YouTube teamed up with satirical newspaper company \"The Onion\" to claim in an uploaded video that the video-sharing website was launched as a contest which had finally come to an end, and would shut down for ten years before being re-launched in 2023, featuring only the winning video. The video starred several YouTube celebrities, including Antoine Dodson. A video of two presenters announcing the nominated videos streamed live for 12 hours.\n", + "0.48: Since its purchase by Google, YouTube has expanded beyond the core website into mobile apps, network television, and the ability to link with other platforms. Video categories on YouTube include music videos, video clips, news, short films, feature films, documentaries, audio recordings, movie trailers, teasers, live streams, vlogs, and more. Most content is generated by individuals, including collaborations between YouTubers and corporate sponsors. Established media corporations such as Disney, Paramount, and Warner Bros. Discovery have also created and expanded their corporate YouTube channels to advertise to a larger audience.\n", + "0.47: YouTube has enabled people to more directly engage with government, such as in the CNN/YouTube presidential debates (2007) in which ordinary people submitted questions to U.S. presidential candidates via YouTube video, with a techPresident co-founder saying that Internet video was changing the political landscape. Describing the Arab Spring (2010–2012), sociologist Philip N. Howard quoted an activist's succinct description that organizing the political unrest involved using \"Facebook to schedule the protests, Twitter to coordinate, and YouTube to tell the world.\" In 2012, more than a third of the U.S. Senate introduced a resolution condemning Joseph Kony 16 days after the \"Kony 2012\" video was posted to YouTube, with resolution co-sponsor Senator Lindsey Graham remarking that the video \"will do more to lead to (Kony's) demise than all other action combined.\"\n", + "0.47: YouTube carried out early experiments with live streaming, including a concert by U2 in 2009, and a question-and-answer session with US President Barack Obama in February 2010. These tests had relied on technology from 3rd-party partners, but in September 2010, YouTube began testing its own live streaming infrastructure. In April 2011, YouTube announced the rollout of \"YouTube Live\". The creation of live streams was initially limited to select partners. It was used for real-time broadcasting of events such as the 2012 Olympics in London. In October 2012, more than 8 million people watched Felix Baumgartner's jump from the edge of space as a live stream on YouTube.\n", + "0.46: In June 2007, YouTube began trials of a system for automatic detection of uploaded videos that infringe copyright. Google CEO Eric Schmidt regarded this system as necessary for resolving lawsuits such as the one from Viacom, which alleged that YouTube profited from content that it did not have the right to distribute. The system, which was initially called \"Video Identification\" and later became known as Content ID, creates an ID File for copyrighted audio and video material, and stores it in a database. When a video is uploaded, it is checked against the database, and flags the video as a copyright violation if a match is found. When this occurs, the content owner has the choice of blocking the video to make it unviewable, tracking the viewing statistics of the video, or adding advertisements to the video.\n", + "0.46: In January 2009, YouTube launched \"YouTube for TV\", a version of the website tailored for set-top boxes and other TV-based media devices with web browsers, initially allowing its videos to be viewed on the PlayStation 3 and Wii video game consoles.\n", + "0.46: In September 2012, YouTube launched its first app for the iPhone, following the decision to drop YouTube as one of the preloaded apps in the iPhone 5 and iOS 6 operating system. According to GlobalWebIndex, YouTube was used by 35% of smartphone users between April and June 2013, making it the third-most used app.\n", + "0.46: Conversely, YouTube has also allowed government to more easily engage with citizens, the White House's official YouTube channel being the seventh top news organization producer on YouTube in 2012 and in 2013 a healthcare exchange commissioned Obama impersonator Iman Crosson's YouTube music video spoof to encourage young Americans to enroll in the Affordable Care Act (Obamacare)-compliant health insurance. In February 2014, U.S. President Obama held a meeting at the White House with leading YouTube content creators to not only promote awareness of Obamacare but more generally to develop ways for government to better connect with the \"YouTube Generation.\" Whereas YouTube's inherent ability to allow presidents to directly connect with average citizens was noted, the YouTube content creators' new media savvy was perceived necessary to better cope with the website's distracting content and fickle audience.\n", + "0.46: Later that year, YouTube came under criticism for showing inappropriate videos targeted at children and often featuring popular characters in violent, sexual or otherwise disturbing situations, many of which appeared on YouTube Kids and attracted millions of views. The term \"Elsagate\" was coined on the Internet and then used by various news outlets to refer to this controversy. On November 11, 2017, YouTube announced it was strengthening site security to protect children from unsuitable content. Later that month, the company started to mass delete videos and channels that made improper use of family-friendly characters. As part of a broader concern regarding child safety on YouTube, the wave of deletions also targeted channels that showed children taking part in inappropriate or dangerous activities under the guidance of adults. Most notably, the company removed \"Toy Freaks\", a channel with over 8.5 million subscribers, that featured a father and his two daughters in odd and upsetting situations. According to analytics specialist SocialBlade, it earned up to £8.7 million annually prior to its deletion.\n", + "0.45: In September 2020, YouTube announced that it would be launching a beta version of a new platform of 15-second videos, similar to TikTok, called YouTube Shorts. The platform was first tested in India but as of March 2021 has expanded to other countries including the United States with videos now able to be up to 1 minute long. The platform is not a standalone app, but is integrated into the main YouTube app. Like TikTok, it gives users access to built-in creative tools, including the possibility of adding licensed music to their videos. The platform had its global beta launch in July 2021.\n" + ] } - ], - "metadata": { + ], + "source": [ + "# Let's query the database\n", + "query = \"What was the first youtube video about?\"\n", + "\n", + "# create the query embedding\n", + "xq = co.embed(\n", + " texts=[query],\n", + " model='embed-english-v3.0',\n", + " input_type='search_query',\n", + " truncate='END'\n", + ").embeddings\n", + "\n", + "print(np.array(xq).shape)\n", + "\n", + "# query, returning the top 20 most similar results\n", + "res = idx.query(xq, top_k=20, include_metadata=True)\n", + "\n", + "# Look at the initial retrieval results\n", + "for match in res['matches']:\n", + " print(f\"{match['score']:.2f}: {match['metadata']['text']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "provenance": [] + "base_uri": "https://localhost:8080/" }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.11.6" + "id": "WaN6U6u19Md6", + "outputId": "9984d8ce-1383-4530-ec84-6e3f3feea05e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.95: YouTube began as a venture capital–funded technology startup. Between November 2005 and April 2006, the company raised money from various investors, with Sequoia Capital, $11.5 million, and Artis Capital Management, $8 million, being the largest two. YouTube's early headquarters were situated above a pizzeria and a Japanese restaurant in San Mateo, California. In February 2005, the company activated codice_1. The first video was uploaded April 23, 2005. Titled \"Me at the zoo\", it shows co-founder Jawed Karim at the San Diego Zoo and can still be viewed on the site. In May, the company launched a public beta and by November, a Nike ad featuring Ronaldinho became the first video to reach one million total views. The site launched officially on December 15, 2005, by which time the site was receiving 8 million views a day. Clips at the time were limited to 100 megabytes, as little as 30 seconds of footage.\n", + "0.92: Karim said the inspiration for YouTube first came from the Super Bowl XXXVIII halftime show controversy when Janet Jackson's breast was briefly exposed by Justin Timberlake during the halftime show. Karim could not easily find video clips of the incident and the 2004 Indian Ocean Tsunami online, which led to the idea of a video-sharing site. Hurley and Chen said that the original idea for YouTube was a video version of an online dating service, and had been influenced by the website Hot or Not. They created posts on Craigslist asking attractive women to upload videos of themselves to YouTube in exchange for a $100 reward. Difficulty in finding enough dating videos led to a change of plans, with the site's founders deciding to accept uploads of any video.\n", + "0.91: YouTube was not the first video-sharing site on the Internet; Vimeo was launched in November 2004, though that site remained a side project of its developers from CollegeHumor at the time and did not grow much, either. The week of YouTube's launch, NBC-Universal's \"Saturday Night Live\" ran a skit \"Lazy Sunday\" by The Lonely Island. Besides helping to bolster ratings and long-term viewership for \"Saturday Night Live\", \"Lazy Sunday\"'s status as an early viral video helped establish YouTube as an important website. Unofficial uploads of the skit to YouTube drew in more than five million collective views by February 2006 before they were removed when NBCUniversal requested it two months later based on copyright concerns. Despite eventually being taken down, these duplicate uploads of the skit helped popularize YouTube's reach and led to the upload of more third-party content. The site grew rapidly; in July 2006, the company announced that more than 65,000 new videos were being uploaded every day and that the site was receiving 100 million video views per day.\n" + ] } + ], + "source": [ + "# Add Cohere Reranking Step\n", + "# embeds=[np.float32(data_array[i]['embedding']) for i in range(len(data_array))]\n", + "docs =[match['metadata']['text'] for match in res['matches']]\n", + "\n", + "rerank_response = co.rerank(\n", + " model = 'rerank-english-v2.0',\n", + " query = query,\n", + " documents = docs,\n", + " top_n = 3,\n", + ")\n", + "for response in rerank_response:\n", + " print(f\"{response.relevance_score:.2f}: {response.document['text']}\")" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/Vanilla_RAG.ipynb b/notebooks/Vanilla_RAG.ipynb index 2f85039c..b7f338c8 100644 --- a/notebooks/Vanilla_RAG.ipynb +++ b/notebooks/Vanilla_RAG.ipynb @@ -1,743 +1,734 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "mz33G3t6gbOl" - }, - "source": [ - "# RAG\n", - "\n", - "Retrieval-Augmented Generation (RAG) is a technique that combines the strengths of pre-trained language models with the ability to retrieve information from a large corpus of documents. RAG **enables the language model to produce more informed, accurate, and contextually relevant answers** than by relying on its pre-trained knowledge alone.\n", - "\n", - "At Cohere, all RAG calls come with... **precise citations**! 🎉\n", - "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", - "These citations make it easy to check where the model’s generated response claims are coming from and they help users gain visibility into the model reasoning. \n", - "\n", - "RAG consists of 3 steps:\n", - "- Step 1: Indexing and given a user query, retrieve the relevant chunks from the index\n", - "- Step 2: Optionally, rerank the retrieved chunks\n", - "- Step 3: Generate the model final answer with **precise citations**, given the retrieved and reranked chunks\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "nSB0pnt0gbOo" - }, - "source": [ - "## Step 0 - Imports & Getting some data\n", - "\n", - "In this example, we'll use a recent piece of text, that wasn't in the training data: the Wikipedia page of the movie \"Dune 2\". \n", - "\n", - "In practice, you would typically do RAG on much longer text, that doesn't fit in the context window of the model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "H787BXXYvD0a", - "outputId": "04ef5e04-7760-4d40-deeb-663536b38f20" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m33.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ], - "source": [ - "# we'll use Cohere to cover all building blocks of RAG\n", - "# TODO: upgrade to \"cohere>5\"\n", - "%pip install \"cohere<5\" --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "rACbepFGgbOo" - }, - "outputs": [], - "source": [ - "import cohere\n", - "API_KEY = \"...\" # fill in your Cohere API key here\n", - "co = cohere.Client(API_KEY)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "QdvbqfFrgbOq", - "outputId": "3882c95c-46bf-4dcc-99a2-453b3c2fc7c4" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for wikipedia (setup.py) ... \u001b[?25l\u001b[?25hdone\n" - ] - } - ], - "source": [ - "# we'll get some wikipedia data\n", - "!pip install wikipedia --quiet\n", - "import wikipedia" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "xP-bWt9XgbOq", - "outputId": "72276fb2-0d6b-415d-af74-452a013ae84b" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The text has roughly 5323 words.\n" - ] - } - ], - "source": [ - "# let's get the wikipedia article about Dune Part Two\n", - "article = wikipedia.page('Dune Part Two')\n", - "text = article.content\n", - "print(f\"The text has roughly {len(text.split())} words.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-1aJ7hKGgbOr" - }, - "source": [ - "## Step 1 - Indexing and given a user query, retrieve the relevant chunks from the index\n", - "\n", - "We index the document in a vector database. This requires getting the documents, chunking them, embedding, and indexing them in a vector database. Then we retrieved relevant results based on the users' query.\n", - "\n", - "### We split the document into chunks of roughly 512 words" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ZUph1JX41665", - "outputId": "6c63a93f-6999-47af-e704-d4a88727bc75" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m256.9/256.9 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.6/66.6 kB\u001b[0m \u001b[31m8.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m138.5/138.5 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ], - "source": [ - "# For chunking let's use langchain to help us split the text\n", - "%pip install -qU langchain-text-splitters --quiet\n", - "from langchain_text_splitters import RecursiveCharacterTextSplitter" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "uhXW7iHC1-Q6", - "outputId": "d68ac348-4b73-4c6a-a445-6c510bdb0881" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The text has been broken down in 91 chunks.\n" - ] - } - ], - "source": [ - "# Create basic configurations to chunk the text\n", - "text_splitter = RecursiveCharacterTextSplitter(\n", - " chunk_size=512,\n", - " chunk_overlap=50,\n", - " length_function=len,\n", - " is_separator_regex=False,\n", - ")\n", - "\n", - "# Split the text into chunks with some overlap\n", - "chunks_ = text_splitter.create_documents([text])\n", - "chunks = [c.page_content for c in chunks_]\n", - "print(f\"The text has been broken down in {len(chunks)} chunks.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "P8g0sE2hgbOs" - }, - "source": [ - "### Embed every text chunk\n", - "\n", - "Cohere embeddings are state-of-the-art." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "KEarMPEqgbOs", - "outputId": "7da0e06d-f637-4470-8e01-6de8249be64b" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "We just computed 91 embeddings.\n" - ] - } - ], - "source": [ - "# Because the texts being embedded are the chunks we are searching over, we set the input type as search_doc\n", - "model=\"embed-english-v3.0\"\n", - "response = co.embed(\n", - " texts= chunks,\n", - " model=model,\n", - " input_type=\"search_document\",\n", - " embedding_types=['float']\n", - ")\n", - "embeddings = response.embeddings.float\n", - "print(f\"We just computed {len(embeddings)} embeddings.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "HM6vKeypgbOs" - }, - "source": [ - "### Store the embeddings in a vector database\n", - "\n", - "We use the simplest vector database ever: a python dictionary using `np.array()`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "sdW7M8HLvB-9" - }, - "outputs": [], - "source": [ - "# We use the simplest vector database ever: a python dictionary\n", - "!pip install numpy --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "H2srFH-IgbOs" - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "vector_database = {i: np.array(embedding) for i, embedding in enumerate(embeddings)}\n", - "# { 0: array([...]), 1: array([...]), 2: array([...]), ..., 10: array([...]) }" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "q6NGVurZgbOs" - }, - "source": [ - "## Given a user query, retrieve the relevant chunks from the vector database\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "eC05yJQ7jlek" - }, - "source": [ - "### Define the user question" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Y2HTxspKgbOs" - }, - "outputs": [], - "source": [ - "query = \"Name everyone involved in writing the script, directing, and producing 'Dune: Part Two'?\"\n", - "\n", - "# Note: the relevant passage in the wikipedia page we're looking for is:\n", - "# \"[...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "9oULg1tOjjOW" - }, - "source": [ - "### Embed the user question\n", - "\n", - "Cohere embeddings are state-of-the-art." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "yrUuS6vXgbOs", - "outputId": "0c64a930-f817-43c2-d775-1d9145cb304e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "query_embedding: [-0.068603516, -0.02947998, -0.06274414, -0.015449524, -0.033294678, 0.0056877136, -0.047210693, 0.04714966, -0.024871826, 0.008148193, 0.0770874, 0.023880005, -0.058685303, -0.052520752, 0.012832642, 0.024398804, 0.0053215027, 0.035491943, 0.02961731, -0.0069847107, 0.01083374, -0.0011358261, -0.002199173, 0.018417358, 0.027389526, -0.002691269, -0.026535034, 0.015197754, 0.024368286, 0.03729248, 0.0057754517, -0.02229309, -0.014694214, 0.019989014, -0.0036315918, -0.013793945, 0.02835083, 0.006011963, 0.011428833, 0.008682251, 0.046142578, -0.040039062, -0.032196045, -0.002653122, -0.012580872, -0.0041618347, 0.03111267, -0.016799927, 0.014801025, -0.00030636787, -0.033050537, 0.033966064, -0.016021729, -0.025009155, -0.007534027, -0.017074585, 0.008415222, -0.10620117, 0.019195557, -0.015686035, -0.0043182373, -0.045440674, 0.05404663, 0.030776978, -0.014129639, -0.01499939, -0.007286072, 0.009933472, 0.06390381, 0.02444458, -0.010345459, 0.041931152, 0.032989502, -0.04522705, 0.056610107, 0.0068893433, -0.008911133, 0.012489319, 0.01675415, 0.020065308, 0.018753052, 0.022659302, -0.051849365, -0.04925537, 0.046325684, -0.005268097, 0.0026874542, -0.036712646, 0.009437561, -0.0037841797, -0.01473999, -0.034179688, -0.0011606216, 0.05026245, 0.0020771027, -0.016021729, -0.0044898987, 0.04168701, -0.015205383, 0.019210815, -0.012374878, -0.031311035, 0.03111267, -0.040100098, -0.016479492, 0.020446777, 0.010192871, 0.0037841797, -0.0023765564, 0.015220642, -0.016571045, -0.006454468, 0.037384033, -0.044555664, -0.008262634, 0.019546509, 0.009460449, 0.014701843, 0.02658081, -0.02078247, 0.015571594, 0.013153076, -0.010375977, 0.047912598, 0.005393982, -0.007911682, -0.019378662, 0.023529053, -0.0033550262, -0.04598999, -0.0052871704, 0.040252686, 0.011375427, 0.01550293, -0.004508972, 0.006515503, 0.003370285, -0.022766113, 0.00062561035, -0.0007596016, -0.0015277863, 0.0149002075, 0.061401367, 8.261204e-05, 0.06359863, -0.01537323, 0.007446289, 0.018814087, 0.02507019, 0.024215698, 0.006122589, 0.005886078, -0.03829956, 0.029037476, 0.07720947, 0.016921997, 0.022109985, 0.005958557, 0.028793335, 0.019485474, 0.015174866, 0.026153564, 0.032318115, 0.034210205, 0.027145386, -0.019515991, -0.018661499, 0.020477295, 0.008598328, -0.06573486, -0.037109375, 0.04043579, 0.030471802, -0.0010843277, 0.009757996, 0.026947021, 0.037017822, -0.018234253, -0.0115356445, 0.099365234, 0.027816772, -0.019927979, 0.0020961761, 0.013198853, -0.019073486, 2.7656555e-05, 0.041259766, 0.029510498, -0.016204834, 0.028137207, 0.039489746, 0.034698486, -0.03918457, -0.029418945, 0.02041626, 0.0073432922, -0.018569946, -0.009849548, 0.002861023, 0.030319214, -0.012886047, 0.014671326, -0.035827637, 0.007247925, -0.027709961, -0.022079468, 0.0012960434, 0.015426636, -0.01725769, 0.01525116, 0.025360107, -0.0077400208, -0.039916992, 0.029037476, -0.011154175, 0.007736206, -0.041748047, 0.05343628, 0.007286072, 0.0435791, 0.034301758, -0.047210693, 0.03552246, -0.015327454, 0.029922485, -0.018859863, 0.013053894, -0.028060913, 0.07757568, -0.020462036, 0.070739746, -0.010223389, 0.03604126, 0.02758789, -0.023284912, 0.012184143, 0.029144287, 0.023880005, -0.019378662, -0.0051116943, 0.0048675537, 0.01864624, -0.04397583, -0.007598877, 0.0713501, 0.0115737915, 0.002922058, 0.011619568, 0.017364502, 0.031921387, -0.0019664764, -0.008575439, 0.003484726, -0.09466553, 0.03475952, 0.026611328, -0.039520264, -0.0104522705, -0.005443573, -0.008392334, 0.012908936, 0.0043792725, -0.002456665, -0.028396606, -0.02027893, -0.0005569458, 0.027786255, 0.03427124, -0.0062332153, -0.018203735, 0.019241333, 0.07244873, -0.0028057098, 0.01234436, -0.0018787384, -0.027496338, 0.0015287399, -0.004032135, -0.013748169, -0.01878357, 0.0018053055, -0.01159668, 0.028213501, 0.004776001, 0.042388916, 0.0024280548, 0.017471313, -0.038085938, 0.026321411, 0.02973938, 0.06213379, 0.006401062, 0.036102295, -0.028121948, -0.00869751, -0.016693115, 0.029190063, 0.016784668, -0.008628845, 0.0039634705, -0.0035381317, 0.019500732, 0.025009155, -0.04547119, -0.003572464, 0.05215454, 0.067871094, -0.04257202, -0.02293396, -0.027175903, 0.05340576, 0.019226074, 0.039978027, 0.056121826, -0.028320312, -0.020217896, -0.035003662, 0.03225708, 0.028656006, 0.062347412, 0.12915039, -0.0137786865, 0.0022201538, -0.057434082, -0.04397583, -0.049865723, -0.013160706, -0.03353882, 0.006427765, -0.014823914, -0.008201599, -0.036346436, -0.037353516, -0.010528564, -0.015930176, -0.027572632, 0.0074272156, 0.004547119, -0.024414062, -0.018859863, -0.020095825, 0.029632568, -0.00067043304, -0.044036865, -0.0043411255, -0.005256653, -0.019195557, 0.022262573, -0.00020956993, -0.013877869, -0.011108398, -0.020324707, -0.015808105, -0.025039673, -0.009498596, 0.05090332, 0.0046195984, -0.017150879, 0.04309082, -0.029067993, 0.002670288, -0.00026249886, -0.032409668, -0.053100586, 0.012481689, -0.014633179, 0.0013475418, -0.034332275, 0.038330078, 0.014892578, -0.046936035, 0.021591187, -0.020385742, -0.0052604675, 0.02796936, 0.0014333725, 0.012077332, -0.0118255615, -0.005569458, 0.008491516, 0.009841919, 0.0031318665, -0.003408432, -0.007144928, 0.040374756, -0.0038928986, 0.005279541, -0.008415222, 0.031707764, 0.0140686035, -0.015029907, -0.02810669, -0.0078125, -0.030853271, -0.03201294, 0.021316528, -0.036193848, -0.0423584, 0.0072784424, 0.014801025, 0.0019607544, -0.012367249, -0.009056091, -0.021438599, -0.02645874, 0.038726807, -0.007549286, 0.0049591064, 0.019012451, 0.017791748, -0.009185791, 0.04006958, 0.003107071, -0.0075302124, -0.010375977, -0.009246826, -0.02130127, -0.0056762695, -0.0076789856, 0.010009766, -0.010536194, 0.041107178, 0.0021133423, 0.029891968, 0.01626587, 0.042236328, -0.02784729, -0.032836914, 0.0317688, 0.045715332, 0.000116825104, 0.028030396, 0.007205963, 0.012512207, -0.035583496, -0.048034668, -0.023529053, -0.04953003, 0.0345459, -0.048339844, -0.060272217, -0.004512787, 0.04425049, 0.0076141357, 0.029510498, 0.007396698, 0.003353119, -0.038726807, 0.07183838, -0.026901245, -0.023529053, -0.038085938, 0.068725586, 0.018096924, -0.013534546, 0.05883789, -0.016113281, 0.017944336, 0.041046143, 0.022918701, 0.036499023, 0.015296936, -0.04916382, 0.0075683594, -0.011390686, 0.009735107, -0.0070152283, 0.003129959, -0.032562256, 0.0003478527, -0.0036640167, -0.006893158, -0.016098022, -0.034332275, 0.037750244, -0.010269165, 0.016494751, -0.02394104, 0.03753662, -0.022644043, -0.0008234978, 0.001001358, -0.048217773, 0.04989624, 0.0078125, 0.0044937134, 0.027038574, 0.04736328, -0.02973938, -0.011726379, 0.01348114, 0.021408081, 0.00844574, -0.03741455, -0.015686035, -0.040893555, 0.001452446, -0.025405884, 0.07348633, 0.038238525, -0.019958496, 0.023071289, -0.016403198, -0.08105469, 0.0071029663, -0.019088745, 5.8174133e-05, -0.005569458, 0.01399231, 0.02255249, 0.011222839, 0.00028824806, 0.0066184998, 0.0017499924, -0.009864807, -0.0115737915, 0.053100586, 0.0065231323, 0.001865387, -0.026428223, 0.03692627, 0.025390625, 0.022613525, 0.018722534, 0.007675171, -0.03439331, 0.041625977, -0.01789856, -0.041046143, 0.0051460266, 0.04144287, 0.048553467, 0.054595947, -0.01108551, -0.033935547, -0.026275635, -0.0118255615, -0.021362305, -0.009841919, -0.00724411, 0.028900146, 0.009887695, -0.023803711, 0.016311646, 0.018798828, -0.03668213, 0.046844482, 0.010696411, -0.014717102, -0.008110046, -0.004589081, -0.0028076172, -0.050811768, -0.017196655, -0.03491211, 0.0074005127, -0.038909912, 0.032440186, -0.034362793, -0.008682251, 0.032928467, -0.04626465, -0.009666443, 0.018951416, 0.031951904, -0.003791809, 0.02015686, -0.05532837, -0.005683899, -0.00054216385, -0.0034332275, 0.008659363, 0.02130127, -0.038879395, -0.0033397675, -0.03866577, -0.0049934387, 0.017944336, 0.001496315, 0.019485474, -0.004348755, 0.00046491623, 0.0007157326, 0.035614014, -0.027694702, 0.03692627, -0.008491516, 0.0524292, -0.016662598, -0.0017795563, -0.021575928, -0.018753052, -0.049346924, -0.06652832, 0.04272461, 0.03186035, 0.0011978149, 0.03463745, 0.024002075, 0.02607727, 0.020446777, 0.0256958, 0.026855469, 0.0074005127, -0.067993164, 0.017944336, -0.0039482117, 0.05496216, -0.041412354, 0.014175415, 0.02444458, -0.026412964, 0.057403564, -0.026779175, 0.023254395, 0.03945923, 0.033569336, -0.030258179, -0.039093018, -0.036468506, 0.017105103, 0.009635925, 0.025497437, 0.04156494, -0.02571106, -0.0010414124, -0.005630493, -0.016448975, -0.026733398, 0.001326561, -0.042022705, 0.0012521744, -0.041259766, -0.12182617, -0.03857422, 0.12548828, -0.005947113, -0.020736694, -0.0033855438, 0.03778076, -0.033813477, 0.038970947, 0.003921509, 0.011810303, 0.031982422, -0.032562256, -0.002653122, -0.025009155, -0.03805542, -0.016998291, 0.018173218, 0.0158844, 0.0011739731, 0.048217773, -0.020401001, 0.044708252, -0.017318726, 0.014457703, -0.041809082, 0.010543823, 0.041931152, 0.076293945, -0.054779053, 0.060272217, -0.046936035, 0.02949524, 0.00554657, 0.041534424, -0.013046265, -0.056152344, 0.010406494, 0.02973938, -0.023727417, -0.022476196, -0.024734497, -0.013168335, 0.060424805, 0.011787415, 0.018997192, -0.043426514, -0.00077724457, -0.010154724, 0.017150879, -0.01171875, -0.022476196, 0.0034255981, -0.0026454926, 0.004837036, -0.0043296814, 0.02619934, -0.021560669, -0.039733887, -0.022415161, -0.06817627, -0.023223877, -0.018585205, -0.015319824, 0.012588501, 0.0064353943, -0.013748169, 0.043304443, 0.002626419, -0.029373169, -0.016784668, -0.026184082, 0.05847168, 0.034179688, 0.03842163, -0.05493164, -0.017486572, 0.016540527, 0.03164673, 0.089904785, 0.013534546, -0.07684326, -0.024108887, 0.07434082, 0.030395508, 0.007091522, 0.07373047, 0.012527466, -0.010856628, -0.01828003, -0.045196533, 0.00065279007, -0.0637207, 0.010726929, 0.023880005, -0.0030708313, -0.012298584, 0.027236938, -0.04928589, 0.023071289, 0.008674622, -0.023529053, -0.015838623, -0.010543823, 0.012168884, 0.014854431, -0.05834961, -0.06088257, -0.012313843, 0.035461426, 0.02027893, 0.019348145, -0.014602661, -0.02104187, -0.0309906, 0.001405716, -0.019973755, -0.00157547, -0.003944397, 0.0009326935, -0.02078247, -0.015731812, -0.044433594, 0.03390503, 0.057159424, 0.018585205, -0.023895264, -0.0057029724, 0.0049552917, 0.013412476, 0.022399902, 0.010154724, 0.0519104, 0.06591797, 0.018341064, 0.012161255, -0.05810547, -0.043304443, -0.031173706, 0.0023860931, -0.003944397, 0.11425781, -0.031036377, 0.019989014, -0.038635254, -0.025939941, 0.035064697, 0.041168213, 0.03161621, -0.069885254, -0.04537964, 0.028945923, -0.023162842, 0.019226074, -0.028442383, 0.015594482, -0.019256592, -0.0046463013, 0.034240723, 0.009124756, 0.05718994, 0.031219482, 0.02154541, 0.009590149, 0.00076818466, 0.04849243, -0.029129028, -0.03375244, -0.023391724, -0.028381348, -0.029708862, -0.0132369995, 0.010353088, 0.020263672, -0.030807495, 0.01007843, -0.03704834, 0.023376465, -0.03665161, 0.03741455, 0.015144348, 0.057281494, 0.03137207, 0.048431396, 0.021194458, 0.008110046, -0.03540039, -0.015312195, 0.022384644, 0.0065956116, 0.008056641, 0.0018348694, -0.009246826, 0.030380249, 0.0003862381, 0.0051841736, 0.04486084, 0.017807007, 0.0026130676, 0.07977295, 0.05419922, 0.062194824, 0.02633667, 0.024841309, -0.041625977, -0.005897522, 0.04031372, -0.055908203, 0.0026226044, -0.05340576, -0.05496216, 0.011474609, -0.006954193, -0.013122559, 0.019714355, -0.07159424, 0.031173706, 0.0034255981, -0.0034103394, 0.0440979, 0.011779785, -0.007827759, -0.03173828, -0.020950317, -0.030166626, -0.035308838, 0.030792236, 0.04525757, -0.028701782, -0.011100769, -0.02331543, -0.0357666, -0.025680542, 0.0011911392, 0.01940918, 0.05706787, 0.028381348, 0.007133484, -0.07733154, -0.007686615, 0.03869629, 0.0066833496, 0.008842468, 0.03439331, -0.014282227, 0.0357666, -0.004737854, -0.039794922, -0.0070381165, 0.02670288, 0.0107421875, 0.016189575, -0.06555176, -0.0138549805, 0.0008363724, -0.016693115, 0.006904602, -0.020263672, -0.030426025, 0.008453369, -0.046173096, -0.01802063, -0.013595581, -0.0044288635, -0.0039978027, -0.0044898987, 0.0007619858, 0.003921509, 0.0053977966, 0.020385742, -0.012329102, -0.023803711, -0.0057525635, 0.038330078, -0.014549255, -0.06298828, -0.047607422, 0.039245605, -0.06781006, -0.035217285, -0.009056091, 0.019927979, -0.003932953, -0.020309448, -0.017044067, 0.018127441, -8.624792e-05, -0.043182373, 0.009590149, 0.035308838, 0.031951904, 0.0011615753, -0.042022705, 0.079956055, 0.026687622, 0.013542175, -0.0074157715, -0.00983429, -0.0022563934, 0.07373047, 0.059387207, 0.03488159, 0.0071372986, -0.06427002, -0.0546875, -0.02482605, 0.11071777, -0.021072388, 0.01626587, -0.049713135, 0.061553955, -0.016860962, 0.051971436, -0.012962341, -0.0011711121, -0.014198303, -0.0061149597, -0.005836487, 0.00022387505, -0.027618408, 0.019836426, 0.009933472, 0.02368164, -0.020309448, -0.0049591064, -0.008628845, -0.03253174, -0.017684937, 0.02468872, -0.0023498535, 0.01448822, 0.061920166, 0.031707764, -0.0026416779, -0.040985107, -0.06335449, -0.036071777, 0.05404663, -0.0044136047, -0.0146102905, -0.0033416748, 0.028671265, -0.012771606, -0.0016565323, -0.0038909912, -0.02407837, -0.009857178, 0.0014467239, -0.008720398, -0.006011963, 0.032073975, -0.033325195, 0.014862061, -0.017227173, -0.018753052, -0.0060424805, 0.022567749, -0.017654419, -0.017562866, -0.07244873, -0.0881958, 0.050476074, 0.02609253, -0.032409668, 0.07458496, 0.009399414, 0.009117126, -0.031051636, -0.03451538, -0.004219055, -0.05718994, 0.020080566, -0.025421143, -0.010948181, 0.06341553, -0.009231567, -0.021697998, -0.009719849, 0.012802124, -0.020370483, 0.0034389496, 0.018859863, -0.025680542, 0.0013141632, 0.068603516, -0.021026611, 0.021881104, -0.0395813, -0.0019073486, 0.0056037903, -0.032348633]\n" - ] - } - ], - "source": [ - "# Because the text being embedded is the search query, we set the input type as search_query\n", - "response = co.embed(\n", - " texts=[query],\n", - " model=model,\n", - " input_type=\"search_query\",\n", - " embedding_types=['float']\n", - ")\n", - "query_embedding = response.embeddings.float[0]\n", - "print(\"query_embedding: \", query_embedding)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8K8B87CGgbOt" - }, - "source": [ - "### Retrieve the most relevant chunks from the vector database\n", - "\n", - "We use cosine similarity to find the most similar chunks" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "mz33G3t6gbOl" + }, + "source": [ + "# RAG\n", + "\n", + "Retrieval-Augmented Generation (RAG) is a technique that combines the strengths of pre-trained language models with the ability to retrieve information from a large corpus of documents. RAG **enables the language model to produce more informed, accurate, and contextually relevant answers** than by relying on its pre-trained knowledge alone.\n", + "\n", + "At Cohere, all RAG calls come with... **precise citations**! 🎉\n", + "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", + "These citations make it easy to check where the model’s generated response claims are coming from and they help users gain visibility into the model reasoning. \n", + "\n", + "RAG consists of 3 steps:\n", + "- Step 1: Indexing and given a user query, retrieve the relevant chunks from the index\n", + "- Step 2: Optionally, rerank the retrieved chunks\n", + "- Step 3: Generate the model final answer with **precise citations**, given the retrieved and reranked chunks\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nSB0pnt0gbOo" + }, + "source": [ + "## Step 0 - Imports & Getting some data\n", + "\n", + "In this example, we'll use a recent piece of text, that wasn't in the training data: the Wikipedia page of the movie \"Dune 2\". \n", + "\n", + "In practice, you would typically do RAG on much longer text, that doesn't fit in the context window of the model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "H787BXXYvD0a", + "outputId": "04ef5e04-7760-4d40-deeb-663536b38f20" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "nik3es32gbOt", - "outputId": "a1c30024-52e1-42c7-8836-a2c590559aca" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "similarity scores: [0.6953257882233425, 0.3713410510180273, 0.46501499776898964, 0.5448546916785195, 0.4014738351361969, 0.3231420292334584, 0.3179003053384008, 0.42799691553367775, 0.18882594531435784, 0.36868801306504106, 0.3404040737300553, 0.3852837621219358, 0.2600249419491577, 0.3723244353775111, 0.3631492691137214, 0.47574774051439606, 0.40415422750911745, 0.4149923346201023, 0.5014741934381444, 0.3549433331883204, 0.32072714802512714, 0.14770872479410424, 0.585277816615252, 0.6999636953772764, 0.7722295084104617, 0.4895347049465806, 0.5170096485954725, 0.7137817366881455, 0.5224900699612323, 0.5914632581598285, 0.2657897083381463, 0.6462342489537262, 0.6317222315431096, 0.5982303530756702, 0.5138265091630297, 0.41385121172723643, 0.4293941094100836, 0.4173182546482015, 0.42621236706314475, 0.4428474375355954, 0.35058541576139896, 0.3578709652019502, 0.3930157841938308, 0.3564608202848675, 0.23016661533167404, 0.4933441863421645, 0.41037089239250985, 0.39993051898770193, 0.3119997063424595, 0.2677143729521374, 0.3700866951454496, 0.46727994925061545, 0.4393343280374425, 0.42111290117172434, 0.4485349189824285, 0.4710573736688592, 0.24169956903740436, 0.3840442910806355, 0.14284631817675886, 0.5381588054138154, 0.431113882725076, 0.5189547209048608, 0.3950667224233914, 0.32429768756510174, 0.4370358125161736, 0.18727062244331039, 0.5206375682478743, 0.5175737635701252, 0.5326043981628349, 0.45586923626994363, 0.21667338125532032, 0.16459878595959285, 0.22236726481673777, 0.5187259906958807, 0.2884444442338396, 0.286407544555338, 0.2313840178160818, 0.2057731158935257, 0.5973876998341746, 0.42904243401792086, 0.4081217538000544, 0.5330523063972133, 0.45080561486977405, 0.414703452285757, 0.2569028899107211, 0.5087916806929323, 0.14159076456040554, 0.46505779053352697, 0.556364222182839, 0.35464351181035236, 0.40174477023626]\n", - "Here are the indices of the top 10 chunks after retrieval: [24 27 23 0 31 32 33 78 29 22]\n", - "Here are the top 10 chunks after retrieval: \n", - "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", - "== that.\"On October 26, 2021, Legendary officially greenlit Dune: Part Two, with a spokesperson for the company stating, \"We would not have gotten to this point without the extraordinary vision of Denis and the amazing work of his talented crew, the writers, our stellar cast, our partners at Warner Bros., and of course the fans! Here's to more Dune.\" Production work had occurred back-to-back with the first film, as Villeneuve and his wife Lapointe immediately took a flight to Budapest in order to begin\n", - "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n", - "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", - "== Eric Roth was hired to co-write the screenplay in April 2017 for the Dune films, and Jon Spaihts was later confirmed to be co-writing the script alongside Roth and Villeneuve. Game of Thrones language creator David Peterson was confirmed to be developing languages for the film in April 2019. Villeneuve and Peterson had created the Chakobsa language, which was used by actors on set. In November 2019, Spaihts stepped down as showrunner for Dune: Prophecy to focus on Dune: Part Two. In June 2020, Greig Fraser\n", - "== on Dune: Part Two. In June 2020, Greig Fraser said, \"It's a fully formed story in itself with places to go. It's a fully standalone epic film that people will get a lot out of when they see it\". Between the release of Dune and the confirmation of Dune: Part Two, Villeneuve started working the script in a way that production could begin immediately once the film was greenlit. By February 2021, Roth created a full treatment for the sequel, with writing beginning that August. He confirmed that Feyd-Rautha\n", - "== that August. He confirmed that Feyd-Rautha would appear in the film, and stated he will be a \"very important character\". In March 2022, Villeneuve had mostly finished writing the screenplay. Craig Mazin and Roth wrote additional literary material for the film.Villeneuve stated that the film would continue directly from the first, and specifically described it as being the \"second part.\" He described the film as being an \"epic war movie\", adding that while the first film was more \"contemplative\", the second\n", - "== On the review aggregator website Rotten Tomatoes, 93% of 378 critics' reviews are positive, with an average rating of 8.4/10. The website's consensus reads: \"Visually thrilling and narratively epic, Dune: Part Two continues Denis Villeneuve's adaptation of the beloved sci-fi series in spectacular form.\" Metacritic, which uses a weighted average, assigned the film a score of 79 out of 100, based on 62 critics, indicating \"generally favorable\" reviews. Audiences surveyed by CinemaScore gave the film an\n", - "== theatrical experience is at the very heart of the cinematic language for me.\" With Dune: Part Two being greenlit, Villeneuve said that his primary concern was to complete the filming as soon as possible, with the earliest he expected to start in the last quarter of 2022. However, he noted that production would be facilitated by the work already established on the first film, which would help expedite production.\n", - "== By November 2016, Legendary Pictures had obtained the film and TV rights for the Dune franchise, based on the eponymous 1965 novel by Frank Herbert. Vice chair of worldwide production for Legendary Mary Parent began discussing with Denis Villeneuve about directing a film adaptation, quickly hiring him after realizing his passion for Dune. By February 2018, Villeneuve was confirmed to be hired as director, and intended to adapt the novel as a two-part film series. Villeneuve ultimately secured a two-film\n" - ] - } - ], - "source": [ - "def cosine_similarity(a, b):\n", - " return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))\n", - "\n", - "# Calculate similarity between the user question & each chunk\n", - "similarities = [cosine_similarity(query_embedding, chunk) for chunk in embeddings]\n", - "print(\"similarity scores: \", similarities)\n", - "\n", - "# Get indices of the top 10 most similar chunks\n", - "sorted_indices = np.argsort(similarities)[::-1]\n", - "\n", - "# Keep only the top 10 indices\n", - "top_indices = sorted_indices[:10]\n", - "print(\"Here are the indices of the top 10 chunks after retrieval: \", top_indices)\n", - "\n", - "# Retrieve the top 10 most similar chunks\n", - "top_chunks_after_retrieval = [chunks[i] for i in top_indices]\n", - "print(\"Here are the top 10 chunks after retrieval: \")\n", - "for t in top_chunks_after_retrieval:\n", - " print(\"== \" + t)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m33.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "# we'll use Cohere to cover all building blocks of RAG\n", + "# TODO: upgrade to \"cohere>5\"\n", + "%pip install \"cohere<5\" --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rACbepFGgbOo" + }, + "outputs": [], + "source": [ + "import cohere\n", + "API_KEY = \"...\" # fill in your Cohere API key here\n", + "co = cohere.Client(API_KEY)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "QdvbqfFrgbOq", + "outputId": "3882c95c-46bf-4dcc-99a2-453b3c2fc7c4" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "qzcpds3VgbOt" - }, - "source": [ - "## Step 2 - Rerank the chunks retrieved from the vector database\n", - "\n", - "We rerank the 10 chunks retrieved from the vector database. Reranking boosts retrieval accuracy.\n", - "\n", - "Reranking lets us go from 10 chunks retrieved from the vector database, to the 3 most relevant chunks." - ] + "name": "stdout", + "output_type": "stream", + "text": [ + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Building wheel for wikipedia (setup.py) ... \u001b[?25l\u001b[?25hdone\n" + ] + } + ], + "source": [ + "# we'll get some wikipedia data\n", + "!pip install wikipedia --quiet\n", + "import wikipedia" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "xP-bWt9XgbOq", + "outputId": "72276fb2-0d6b-415d-af74-452a013ae84b" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "2J4LywVygbOt", - "outputId": "7a4c89bf-fc5e-409f-9304-fce006b9d8bf" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Here are the top 3 chunks after rerank: \n", - "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", - "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", - "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n" - ] - } - ], - "source": [ - "response = co.rerank(\n", - " query=query,\n", - " documents=top_chunks_after_retrieval,\n", - " top_n=3,\n", - " model=\"rerank-english-v2.0\",\n", - ")\n", - "\n", - "top_chunks_after_rerank = [result.document['text'] for result in response]\n", - "print(\"Here are the top 3 chunks after rerank: \")\n", - "for t in top_chunks_after_rerank:\n", - " print(\"== \" + t)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "The text has roughly 5323 words.\n" + ] + } + ], + "source": [ + "# let's get the wikipedia article about Dune Part Two\n", + "article = wikipedia.page('Dune Part Two')\n", + "text = article.content\n", + "print(f\"The text has roughly {len(text.split())} words.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1aJ7hKGgbOr" + }, + "source": [ + "## Step 1 - Indexing and given a user query, retrieve the relevant chunks from the index\n", + "\n", + "We index the document in a vector database. This requires getting the documents, chunking them, embedding, and indexing them in a vector database. Then we retrieved relevant results based on the users' query.\n", + "\n", + "### We split the document into chunks of roughly 512 words" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "ZUph1JX41665", + "outputId": "6c63a93f-6999-47af-e704-d4a88727bc75" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "KuPL0VUXgbOt" - }, - "source": [ - "## Step 3 - Generate the model final answer, given the retrieved and reranked chunks" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m256.9/256.9 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.6/66.6 kB\u001b[0m \u001b[31m8.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m138.5/138.5 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "# For chunking let's use langchain to help us split the text\n", + "%pip install -qU langchain-text-splitters --quiet\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "uhXW7iHC1-Q6", + "outputId": "d68ac348-4b73-4c6a-a445-6c510bdb0881" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "oCNXWH8GgbOt" - }, - "outputs": [], - "source": [ - "# preamble containing instructions about the task and the desired style for the output.\n", - "preamble = \"\"\"\n", - "## Task & Context\n", - "You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n", - "\n", - "## Style Guide\n", - "Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\n", - "\"\"\"" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "The text has been broken down in 91 chunks.\n" + ] + } + ], + "source": [ + "# Create basic configurations to chunk the text\n", + "text_splitter = RecursiveCharacterTextSplitter(\n", + " chunk_size=512,\n", + " chunk_overlap=50,\n", + " length_function=len,\n", + " is_separator_regex=False,\n", + ")\n", + "\n", + "# Split the text into chunks with some overlap\n", + "chunks_ = text_splitter.create_documents([text])\n", + "chunks = [c.page_content for c in chunks_]\n", + "print(f\"The text has been broken down in {len(chunks)} chunks.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8g0sE2hgbOs" + }, + "source": [ + "### Embed every text chunk\n", + "\n", + "Cohere embeddings are state-of-the-art." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "KEarMPEqgbOs", + "outputId": "7da0e06d-f637-4470-8e01-6de8249be64b" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "BevatShtgbOt", - "outputId": "af71f4a9-787a-4ee3-9598-20692fb3bf16" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Final answer:\n", - "Here are the key crew members involved in 'Dune: Part Two':\n", - "\n", - "- Denis Villeneuve: director and producer\n", - "- Jon Spaihts: co-writer of the screenplay\n", - "- Mary Parent and Cale Boyter: producers \n", - "- Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Richard P. Rubinstein, John Harrison, Herbert W. Gain and Kevin J. Anderson: executive producers \n", - "- Joe Walker: editor\n", - "- Brad Riker: supervising art director\n", - "- Patrice Vermette: production designer\n", - "- Paul Lambert: visual effects supervisor\n", - "- Gerd Nefzer: special effects supervisor\n", - "- Thomas Struthers: stunt coordinator. \n", - "\n", - "A number of crew members from the first film returned for the sequel, which is set to be released in 2024.\n" - ] - } - ], - "source": [ - "# retrieved documents\n", - "documents = [\n", - " {\"title\": \"chunk 0\", \"snippet\": top_chunks_after_rerank[0]},\n", - " {\"title\": \"chunk 1\", \"snippet\": top_chunks_after_rerank[1]},\n", - " {\"title\": \"chunk 2\", \"snippet\": top_chunks_after_rerank[2]},\n", - " ]\n", - "\n", - "# get model response\n", - "response = co.chat(\n", - " message=query,\n", - " documents=documents,\n", - " preamble=preamble,\n", - " model=\"command-r\",\n", - " temperature=0.3\n", - ")\n", - "\n", - "print(\"Final answer:\")\n", - "print(response.text)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "We just computed 91 embeddings.\n" + ] + } + ], + "source": [ + "# Because the texts being embedded are the chunks we are searching over, we set the input type as search_doc\n", + "model=\"embed-english-v3.0\"\n", + "response = co.embed(\n", + " texts= chunks,\n", + " model=model,\n", + " input_type=\"search_document\",\n", + " embedding_types=['float']\n", + ")\n", + "embeddings = response.embeddings.float\n", + "print(f\"We just computed {len(embeddings)} embeddings.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HM6vKeypgbOs" + }, + "source": [ + "### Store the embeddings in a vector database\n", + "\n", + "We use the simplest vector database ever: a python dictionary using `np.array()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sdW7M8HLvB-9" + }, + "outputs": [], + "source": [ + "# We use the simplest vector database ever: a python dictionary\n", + "!pip install numpy --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "H2srFH-IgbOs" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "vector_database = {i: np.array(embedding) for i, embedding in enumerate(embeddings)}\n", + "# { 0: array([...]), 1: array([...]), 2: array([...]), ..., 10: array([...]) }" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q6NGVurZgbOs" + }, + "source": [ + "## Given a user query, retrieve the relevant chunks from the vector database\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eC05yJQ7jlek" + }, + "source": [ + "### Define the user question" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Y2HTxspKgbOs" + }, + "outputs": [], + "source": [ + "query = \"Name everyone involved in writing the script, directing, and producing 'Dune: Part Two'?\"\n", + "\n", + "# Note: the relevant passage in the wikipedia page we're looking for is:\n", + "# \"[...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oULg1tOjjOW" + }, + "source": [ + "### Embed the user question\n", + "\n", + "Cohere embeddings are state-of-the-art." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "yrUuS6vXgbOs", + "outputId": "0c64a930-f817-43c2-d775-1d9145cb304e" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "20wcn-EjlXZd" - }, - "source": [ - "Note: this is indeed the answer you'd expect, and here was the passage of text in wikipedia explaining it!\n", - "\n", - "\" [...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "query_embedding: [-0.068603516, -0.02947998, -0.06274414, -0.015449524, -0.033294678, 0.0056877136, -0.047210693, 0.04714966, -0.024871826, 0.008148193, 0.0770874, 0.023880005, -0.058685303, -0.052520752, 0.012832642, 0.024398804, 0.0053215027, 0.035491943, 0.02961731, -0.0069847107, 0.01083374, -0.0011358261, -0.002199173, 0.018417358, 0.027389526, -0.002691269, -0.026535034, 0.015197754, 0.024368286, 0.03729248, 0.0057754517, -0.02229309, -0.014694214, 0.019989014, -0.0036315918, -0.013793945, 0.02835083, 0.006011963, 0.011428833, 0.008682251, 0.046142578, -0.040039062, -0.032196045, -0.002653122, -0.012580872, -0.0041618347, 0.03111267, -0.016799927, 0.014801025, -0.00030636787, -0.033050537, 0.033966064, -0.016021729, -0.025009155, -0.007534027, -0.017074585, 0.008415222, -0.10620117, 0.019195557, -0.015686035, -0.0043182373, -0.045440674, 0.05404663, 0.030776978, -0.014129639, -0.01499939, -0.007286072, 0.009933472, 0.06390381, 0.02444458, -0.010345459, 0.041931152, 0.032989502, -0.04522705, 0.056610107, 0.0068893433, -0.008911133, 0.012489319, 0.01675415, 0.020065308, 0.018753052, 0.022659302, -0.051849365, -0.04925537, 0.046325684, -0.005268097, 0.0026874542, -0.036712646, 0.009437561, -0.0037841797, -0.01473999, -0.034179688, -0.0011606216, 0.05026245, 0.0020771027, -0.016021729, -0.0044898987, 0.04168701, -0.015205383, 0.019210815, -0.012374878, -0.031311035, 0.03111267, -0.040100098, -0.016479492, 0.020446777, 0.010192871, 0.0037841797, -0.0023765564, 0.015220642, -0.016571045, -0.006454468, 0.037384033, -0.044555664, -0.008262634, 0.019546509, 0.009460449, 0.014701843, 0.02658081, -0.02078247, 0.015571594, 0.013153076, -0.010375977, 0.047912598, 0.005393982, -0.007911682, -0.019378662, 0.023529053, -0.0033550262, -0.04598999, -0.0052871704, 0.040252686, 0.011375427, 0.01550293, -0.004508972, 0.006515503, 0.003370285, -0.022766113, 0.00062561035, -0.0007596016, -0.0015277863, 0.0149002075, 0.061401367, 8.261204e-05, 0.06359863, -0.01537323, 0.007446289, 0.018814087, 0.02507019, 0.024215698, 0.006122589, 0.005886078, -0.03829956, 0.029037476, 0.07720947, 0.016921997, 0.022109985, 0.005958557, 0.028793335, 0.019485474, 0.015174866, 0.026153564, 0.032318115, 0.034210205, 0.027145386, -0.019515991, -0.018661499, 0.020477295, 0.008598328, -0.06573486, -0.037109375, 0.04043579, 0.030471802, -0.0010843277, 0.009757996, 0.026947021, 0.037017822, -0.018234253, -0.0115356445, 0.099365234, 0.027816772, -0.019927979, 0.0020961761, 0.013198853, -0.019073486, 2.7656555e-05, 0.041259766, 0.029510498, -0.016204834, 0.028137207, 0.039489746, 0.034698486, -0.03918457, -0.029418945, 0.02041626, 0.0073432922, -0.018569946, -0.009849548, 0.002861023, 0.030319214, -0.012886047, 0.014671326, -0.035827637, 0.007247925, -0.027709961, -0.022079468, 0.0012960434, 0.015426636, -0.01725769, 0.01525116, 0.025360107, -0.0077400208, -0.039916992, 0.029037476, -0.011154175, 0.007736206, -0.041748047, 0.05343628, 0.007286072, 0.0435791, 0.034301758, -0.047210693, 0.03552246, -0.015327454, 0.029922485, -0.018859863, 0.013053894, -0.028060913, 0.07757568, -0.020462036, 0.070739746, -0.010223389, 0.03604126, 0.02758789, -0.023284912, 0.012184143, 0.029144287, 0.023880005, -0.019378662, -0.0051116943, 0.0048675537, 0.01864624, -0.04397583, -0.007598877, 0.0713501, 0.0115737915, 0.002922058, 0.011619568, 0.017364502, 0.031921387, -0.0019664764, -0.008575439, 0.003484726, -0.09466553, 0.03475952, 0.026611328, -0.039520264, -0.0104522705, -0.005443573, -0.008392334, 0.012908936, 0.0043792725, -0.002456665, -0.028396606, -0.02027893, -0.0005569458, 0.027786255, 0.03427124, -0.0062332153, -0.018203735, 0.019241333, 0.07244873, -0.0028057098, 0.01234436, -0.0018787384, -0.027496338, 0.0015287399, -0.004032135, -0.013748169, -0.01878357, 0.0018053055, -0.01159668, 0.028213501, 0.004776001, 0.042388916, 0.0024280548, 0.017471313, -0.038085938, 0.026321411, 0.02973938, 0.06213379, 0.006401062, 0.036102295, -0.028121948, -0.00869751, -0.016693115, 0.029190063, 0.016784668, -0.008628845, 0.0039634705, -0.0035381317, 0.019500732, 0.025009155, -0.04547119, -0.003572464, 0.05215454, 0.067871094, -0.04257202, -0.02293396, -0.027175903, 0.05340576, 0.019226074, 0.039978027, 0.056121826, -0.028320312, -0.020217896, -0.035003662, 0.03225708, 0.028656006, 0.062347412, 0.12915039, -0.0137786865, 0.0022201538, -0.057434082, -0.04397583, -0.049865723, -0.013160706, -0.03353882, 0.006427765, -0.014823914, -0.008201599, -0.036346436, -0.037353516, -0.010528564, -0.015930176, -0.027572632, 0.0074272156, 0.004547119, -0.024414062, -0.018859863, -0.020095825, 0.029632568, -0.00067043304, -0.044036865, -0.0043411255, -0.005256653, -0.019195557, 0.022262573, -0.00020956993, -0.013877869, -0.011108398, -0.020324707, -0.015808105, -0.025039673, -0.009498596, 0.05090332, 0.0046195984, -0.017150879, 0.04309082, -0.029067993, 0.002670288, -0.00026249886, -0.032409668, -0.053100586, 0.012481689, -0.014633179, 0.0013475418, -0.034332275, 0.038330078, 0.014892578, -0.046936035, 0.021591187, -0.020385742, -0.0052604675, 0.02796936, 0.0014333725, 0.012077332, -0.0118255615, -0.005569458, 0.008491516, 0.009841919, 0.0031318665, -0.003408432, -0.007144928, 0.040374756, -0.0038928986, 0.005279541, -0.008415222, 0.031707764, 0.0140686035, -0.015029907, -0.02810669, -0.0078125, -0.030853271, -0.03201294, 0.021316528, -0.036193848, -0.0423584, 0.0072784424, 0.014801025, 0.0019607544, -0.012367249, -0.009056091, -0.021438599, -0.02645874, 0.038726807, -0.007549286, 0.0049591064, 0.019012451, 0.017791748, -0.009185791, 0.04006958, 0.003107071, -0.0075302124, -0.010375977, -0.009246826, -0.02130127, -0.0056762695, -0.0076789856, 0.010009766, -0.010536194, 0.041107178, 0.0021133423, 0.029891968, 0.01626587, 0.042236328, -0.02784729, -0.032836914, 0.0317688, 0.045715332, 0.000116825104, 0.028030396, 0.007205963, 0.012512207, -0.035583496, -0.048034668, -0.023529053, -0.04953003, 0.0345459, -0.048339844, -0.060272217, -0.004512787, 0.04425049, 0.0076141357, 0.029510498, 0.007396698, 0.003353119, -0.038726807, 0.07183838, -0.026901245, -0.023529053, -0.038085938, 0.068725586, 0.018096924, -0.013534546, 0.05883789, -0.016113281, 0.017944336, 0.041046143, 0.022918701, 0.036499023, 0.015296936, -0.04916382, 0.0075683594, -0.011390686, 0.009735107, -0.0070152283, 0.003129959, -0.032562256, 0.0003478527, -0.0036640167, -0.006893158, -0.016098022, -0.034332275, 0.037750244, -0.010269165, 0.016494751, -0.02394104, 0.03753662, -0.022644043, -0.0008234978, 0.001001358, -0.048217773, 0.04989624, 0.0078125, 0.0044937134, 0.027038574, 0.04736328, -0.02973938, -0.011726379, 0.01348114, 0.021408081, 0.00844574, -0.03741455, -0.015686035, -0.040893555, 0.001452446, -0.025405884, 0.07348633, 0.038238525, -0.019958496, 0.023071289, -0.016403198, -0.08105469, 0.0071029663, -0.019088745, 5.8174133e-05, -0.005569458, 0.01399231, 0.02255249, 0.011222839, 0.00028824806, 0.0066184998, 0.0017499924, -0.009864807, -0.0115737915, 0.053100586, 0.0065231323, 0.001865387, -0.026428223, 0.03692627, 0.025390625, 0.022613525, 0.018722534, 0.007675171, -0.03439331, 0.041625977, -0.01789856, -0.041046143, 0.0051460266, 0.04144287, 0.048553467, 0.054595947, -0.01108551, -0.033935547, -0.026275635, -0.0118255615, -0.021362305, -0.009841919, -0.00724411, 0.028900146, 0.009887695, -0.023803711, 0.016311646, 0.018798828, -0.03668213, 0.046844482, 0.010696411, -0.014717102, -0.008110046, -0.004589081, -0.0028076172, -0.050811768, -0.017196655, -0.03491211, 0.0074005127, -0.038909912, 0.032440186, -0.034362793, -0.008682251, 0.032928467, -0.04626465, -0.009666443, 0.018951416, 0.031951904, -0.003791809, 0.02015686, -0.05532837, -0.005683899, -0.00054216385, -0.0034332275, 0.008659363, 0.02130127, -0.038879395, -0.0033397675, -0.03866577, -0.0049934387, 0.017944336, 0.001496315, 0.019485474, -0.004348755, 0.00046491623, 0.0007157326, 0.035614014, -0.027694702, 0.03692627, -0.008491516, 0.0524292, -0.016662598, -0.0017795563, -0.021575928, -0.018753052, -0.049346924, -0.06652832, 0.04272461, 0.03186035, 0.0011978149, 0.03463745, 0.024002075, 0.02607727, 0.020446777, 0.0256958, 0.026855469, 0.0074005127, -0.067993164, 0.017944336, -0.0039482117, 0.05496216, -0.041412354, 0.014175415, 0.02444458, -0.026412964, 0.057403564, -0.026779175, 0.023254395, 0.03945923, 0.033569336, -0.030258179, -0.039093018, -0.036468506, 0.017105103, 0.009635925, 0.025497437, 0.04156494, -0.02571106, -0.0010414124, -0.005630493, -0.016448975, -0.026733398, 0.001326561, -0.042022705, 0.0012521744, -0.041259766, -0.12182617, -0.03857422, 0.12548828, -0.005947113, -0.020736694, -0.0033855438, 0.03778076, -0.033813477, 0.038970947, 0.003921509, 0.011810303, 0.031982422, -0.032562256, -0.002653122, -0.025009155, -0.03805542, -0.016998291, 0.018173218, 0.0158844, 0.0011739731, 0.048217773, -0.020401001, 0.044708252, -0.017318726, 0.014457703, -0.041809082, 0.010543823, 0.041931152, 0.076293945, -0.054779053, 0.060272217, -0.046936035, 0.02949524, 0.00554657, 0.041534424, -0.013046265, -0.056152344, 0.010406494, 0.02973938, -0.023727417, -0.022476196, -0.024734497, -0.013168335, 0.060424805, 0.011787415, 0.018997192, -0.043426514, -0.00077724457, -0.010154724, 0.017150879, -0.01171875, -0.022476196, 0.0034255981, -0.0026454926, 0.004837036, -0.0043296814, 0.02619934, -0.021560669, -0.039733887, -0.022415161, -0.06817627, -0.023223877, -0.018585205, -0.015319824, 0.012588501, 0.0064353943, -0.013748169, 0.043304443, 0.002626419, -0.029373169, -0.016784668, -0.026184082, 0.05847168, 0.034179688, 0.03842163, -0.05493164, -0.017486572, 0.016540527, 0.03164673, 0.089904785, 0.013534546, -0.07684326, -0.024108887, 0.07434082, 0.030395508, 0.007091522, 0.07373047, 0.012527466, -0.010856628, -0.01828003, -0.045196533, 0.00065279007, -0.0637207, 0.010726929, 0.023880005, -0.0030708313, -0.012298584, 0.027236938, -0.04928589, 0.023071289, 0.008674622, -0.023529053, -0.015838623, -0.010543823, 0.012168884, 0.014854431, -0.05834961, -0.06088257, -0.012313843, 0.035461426, 0.02027893, 0.019348145, -0.014602661, -0.02104187, -0.0309906, 0.001405716, -0.019973755, -0.00157547, -0.003944397, 0.0009326935, -0.02078247, -0.015731812, -0.044433594, 0.03390503, 0.057159424, 0.018585205, -0.023895264, -0.0057029724, 0.0049552917, 0.013412476, 0.022399902, 0.010154724, 0.0519104, 0.06591797, 0.018341064, 0.012161255, -0.05810547, -0.043304443, -0.031173706, 0.0023860931, -0.003944397, 0.11425781, -0.031036377, 0.019989014, -0.038635254, -0.025939941, 0.035064697, 0.041168213, 0.03161621, -0.069885254, -0.04537964, 0.028945923, -0.023162842, 0.019226074, -0.028442383, 0.015594482, -0.019256592, -0.0046463013, 0.034240723, 0.009124756, 0.05718994, 0.031219482, 0.02154541, 0.009590149, 0.00076818466, 0.04849243, -0.029129028, -0.03375244, -0.023391724, -0.028381348, -0.029708862, -0.0132369995, 0.010353088, 0.020263672, -0.030807495, 0.01007843, -0.03704834, 0.023376465, -0.03665161, 0.03741455, 0.015144348, 0.057281494, 0.03137207, 0.048431396, 0.021194458, 0.008110046, -0.03540039, -0.015312195, 0.022384644, 0.0065956116, 0.008056641, 0.0018348694, -0.009246826, 0.030380249, 0.0003862381, 0.0051841736, 0.04486084, 0.017807007, 0.0026130676, 0.07977295, 0.05419922, 0.062194824, 0.02633667, 0.024841309, -0.041625977, -0.005897522, 0.04031372, -0.055908203, 0.0026226044, -0.05340576, -0.05496216, 0.011474609, -0.006954193, -0.013122559, 0.019714355, -0.07159424, 0.031173706, 0.0034255981, -0.0034103394, 0.0440979, 0.011779785, -0.007827759, -0.03173828, -0.020950317, -0.030166626, -0.035308838, 0.030792236, 0.04525757, -0.028701782, -0.011100769, -0.02331543, -0.0357666, -0.025680542, 0.0011911392, 0.01940918, 0.05706787, 0.028381348, 0.007133484, -0.07733154, -0.007686615, 0.03869629, 0.0066833496, 0.008842468, 0.03439331, -0.014282227, 0.0357666, -0.004737854, -0.039794922, -0.0070381165, 0.02670288, 0.0107421875, 0.016189575, -0.06555176, -0.0138549805, 0.0008363724, -0.016693115, 0.006904602, -0.020263672, -0.030426025, 0.008453369, -0.046173096, -0.01802063, -0.013595581, -0.0044288635, -0.0039978027, -0.0044898987, 0.0007619858, 0.003921509, 0.0053977966, 0.020385742, -0.012329102, -0.023803711, -0.0057525635, 0.038330078, -0.014549255, -0.06298828, -0.047607422, 0.039245605, -0.06781006, -0.035217285, -0.009056091, 0.019927979, -0.003932953, -0.020309448, -0.017044067, 0.018127441, -8.624792e-05, -0.043182373, 0.009590149, 0.035308838, 0.031951904, 0.0011615753, -0.042022705, 0.079956055, 0.026687622, 0.013542175, -0.0074157715, -0.00983429, -0.0022563934, 0.07373047, 0.059387207, 0.03488159, 0.0071372986, -0.06427002, -0.0546875, -0.02482605, 0.11071777, -0.021072388, 0.01626587, -0.049713135, 0.061553955, -0.016860962, 0.051971436, -0.012962341, -0.0011711121, -0.014198303, -0.0061149597, -0.005836487, 0.00022387505, -0.027618408, 0.019836426, 0.009933472, 0.02368164, -0.020309448, -0.0049591064, -0.008628845, -0.03253174, -0.017684937, 0.02468872, -0.0023498535, 0.01448822, 0.061920166, 0.031707764, -0.0026416779, -0.040985107, -0.06335449, -0.036071777, 0.05404663, -0.0044136047, -0.0146102905, -0.0033416748, 0.028671265, -0.012771606, -0.0016565323, -0.0038909912, -0.02407837, -0.009857178, 0.0014467239, -0.008720398, -0.006011963, 0.032073975, -0.033325195, 0.014862061, -0.017227173, -0.018753052, -0.0060424805, 0.022567749, -0.017654419, -0.017562866, -0.07244873, -0.0881958, 0.050476074, 0.02609253, -0.032409668, 0.07458496, 0.009399414, 0.009117126, -0.031051636, -0.03451538, -0.004219055, -0.05718994, 0.020080566, -0.025421143, -0.010948181, 0.06341553, -0.009231567, -0.021697998, -0.009719849, 0.012802124, -0.020370483, 0.0034389496, 0.018859863, -0.025680542, 0.0013141632, 0.068603516, -0.021026611, 0.021881104, -0.0395813, -0.0019073486, 0.0056037903, -0.032348633]\n" + ] + } + ], + "source": [ + "# Because the text being embedded is the search query, we set the input type as search_query\n", + "response = co.embed(\n", + " texts=[query],\n", + " model=model,\n", + " input_type=\"search_query\",\n", + " embedding_types=['float']\n", + ")\n", + "query_embedding = response.embeddings.float[0]\n", + "print(\"query_embedding: \", query_embedding)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8K8B87CGgbOt" + }, + "source": [ + "### Retrieve the most relevant chunks from the vector database\n", + "\n", + "We use cosine similarity to find the most similar chunks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "nik3es32gbOt", + "outputId": "a1c30024-52e1-42c7-8836-a2c590559aca" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "RoSVDXSsgbOt" - }, - "source": [ - "## Bonus: Citations come for free with Cohere! 🎉\n", - "\n", - "At Cohere, all RAG calls come with... precise citations! 🎉\n", - "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", - "These citations make it easy to check where the model’s generated response claims are coming from. \n", - "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", - "These citations are optional — you can decide to ignore them.\n" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "similarity scores: [0.6953257882233425, 0.3713410510180273, 0.46501499776898964, 0.5448546916785195, 0.4014738351361969, 0.3231420292334584, 0.3179003053384008, 0.42799691553367775, 0.18882594531435784, 0.36868801306504106, 0.3404040737300553, 0.3852837621219358, 0.2600249419491577, 0.3723244353775111, 0.3631492691137214, 0.47574774051439606, 0.40415422750911745, 0.4149923346201023, 0.5014741934381444, 0.3549433331883204, 0.32072714802512714, 0.14770872479410424, 0.585277816615252, 0.6999636953772764, 0.7722295084104617, 0.4895347049465806, 0.5170096485954725, 0.7137817366881455, 0.5224900699612323, 0.5914632581598285, 0.2657897083381463, 0.6462342489537262, 0.6317222315431096, 0.5982303530756702, 0.5138265091630297, 0.41385121172723643, 0.4293941094100836, 0.4173182546482015, 0.42621236706314475, 0.4428474375355954, 0.35058541576139896, 0.3578709652019502, 0.3930157841938308, 0.3564608202848675, 0.23016661533167404, 0.4933441863421645, 0.41037089239250985, 0.39993051898770193, 0.3119997063424595, 0.2677143729521374, 0.3700866951454496, 0.46727994925061545, 0.4393343280374425, 0.42111290117172434, 0.4485349189824285, 0.4710573736688592, 0.24169956903740436, 0.3840442910806355, 0.14284631817675886, 0.5381588054138154, 0.431113882725076, 0.5189547209048608, 0.3950667224233914, 0.32429768756510174, 0.4370358125161736, 0.18727062244331039, 0.5206375682478743, 0.5175737635701252, 0.5326043981628349, 0.45586923626994363, 0.21667338125532032, 0.16459878595959285, 0.22236726481673777, 0.5187259906958807, 0.2884444442338396, 0.286407544555338, 0.2313840178160818, 0.2057731158935257, 0.5973876998341746, 0.42904243401792086, 0.4081217538000544, 0.5330523063972133, 0.45080561486977405, 0.414703452285757, 0.2569028899107211, 0.5087916806929323, 0.14159076456040554, 0.46505779053352697, 0.556364222182839, 0.35464351181035236, 0.40174477023626]\n", + "Here are the indices of the top 10 chunks after retrieval: [24 27 23 0 31 32 33 78 29 22]\n", + "Here are the top 10 chunks after retrieval: \n", + "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", + "== that.\"On October 26, 2021, Legendary officially greenlit Dune: Part Two, with a spokesperson for the company stating, \"We would not have gotten to this point without the extraordinary vision of Denis and the amazing work of his talented crew, the writers, our stellar cast, our partners at Warner Bros., and of course the fans! Here's to more Dune.\" Production work had occurred back-to-back with the first film, as Villeneuve and his wife Lapointe immediately took a flight to Budapest in order to begin\n", + "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n", + "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", + "== Eric Roth was hired to co-write the screenplay in April 2017 for the Dune films, and Jon Spaihts was later confirmed to be co-writing the script alongside Roth and Villeneuve. Game of Thrones language creator David Peterson was confirmed to be developing languages for the film in April 2019. Villeneuve and Peterson had created the Chakobsa language, which was used by actors on set. In November 2019, Spaihts stepped down as showrunner for Dune: Prophecy to focus on Dune: Part Two. In June 2020, Greig Fraser\n", + "== on Dune: Part Two. In June 2020, Greig Fraser said, \"It's a fully formed story in itself with places to go. It's a fully standalone epic film that people will get a lot out of when they see it\". Between the release of Dune and the confirmation of Dune: Part Two, Villeneuve started working the script in a way that production could begin immediately once the film was greenlit. By February 2021, Roth created a full treatment for the sequel, with writing beginning that August. He confirmed that Feyd-Rautha\n", + "== that August. He confirmed that Feyd-Rautha would appear in the film, and stated he will be a \"very important character\". In March 2022, Villeneuve had mostly finished writing the screenplay. Craig Mazin and Roth wrote additional literary material for the film.Villeneuve stated that the film would continue directly from the first, and specifically described it as being the \"second part.\" He described the film as being an \"epic war movie\", adding that while the first film was more \"contemplative\", the second\n", + "== On the review aggregator website Rotten Tomatoes, 93% of 378 critics' reviews are positive, with an average rating of 8.4/10. The website's consensus reads: \"Visually thrilling and narratively epic, Dune: Part Two continues Denis Villeneuve's adaptation of the beloved sci-fi series in spectacular form.\" Metacritic, which uses a weighted average, assigned the film a score of 79 out of 100, based on 62 critics, indicating \"generally favorable\" reviews. Audiences surveyed by CinemaScore gave the film an\n", + "== theatrical experience is at the very heart of the cinematic language for me.\" With Dune: Part Two being greenlit, Villeneuve said that his primary concern was to complete the filming as soon as possible, with the earliest he expected to start in the last quarter of 2022. However, he noted that production would be facilitated by the work already established on the first film, which would help expedite production.\n", + "== By November 2016, Legendary Pictures had obtained the film and TV rights for the Dune franchise, based on the eponymous 1965 novel by Frank Herbert. Vice chair of worldwide production for Legendary Mary Parent began discussing with Denis Villeneuve about directing a film adaptation, quickly hiring him after realizing his passion for Dune. By February 2018, Villeneuve was confirmed to be hired as director, and intended to adapt the novel as a two-part film series. Villeneuve ultimately secured a two-film\n" + ] + } + ], + "source": [ + "def cosine_similarity(a, b):\n", + " return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))\n", + "\n", + "# Calculate similarity between the user question & each chunk\n", + "similarities = [cosine_similarity(query_embedding, chunk) for chunk in embeddings]\n", + "print(\"similarity scores: \", similarities)\n", + "\n", + "# Get indices of the top 10 most similar chunks\n", + "sorted_indices = np.argsort(similarities)[::-1]\n", + "\n", + "# Keep only the top 10 indices\n", + "top_indices = sorted_indices[:10]\n", + "print(\"Here are the indices of the top 10 chunks after retrieval: \", top_indices)\n", + "\n", + "# Retrieve the top 10 most similar chunks\n", + "top_chunks_after_retrieval = [chunks[i] for i in top_indices]\n", + "print(\"Here are the top 10 chunks after retrieval: \")\n", + "for t in top_chunks_after_retrieval:\n", + " print(\"== \" + t)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qzcpds3VgbOt" + }, + "source": [ + "## Step 2 - Rerank the chunks retrieved from the vector database\n", + "\n", + "We rerank the 10 chunks retrieved from the vector database. Reranking boosts retrieval accuracy.\n", + "\n", + "Reranking lets us go from 10 chunks retrieved from the vector database, to the 3 most relevant chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "2J4LywVygbOt", + "outputId": "7a4c89bf-fc5e-409f-9304-fce006b9d8bf" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "BVTuQdmDgbOt", - "outputId": "f843b262-d8bb-45ba-cbfb-9915da104eda" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Citations that support the final answer:\n", - "{'start': 63, 'end': 79, 'text': 'Denis Villeneuve', 'document_ids': ['doc_0']}\n", - "{'start': 81, 'end': 102, 'text': 'director and producer', 'document_ids': ['doc_0']}\n", - "{'start': 105, 'end': 116, 'text': 'Jon Spaihts', 'document_ids': ['doc_0']}\n", - "{'start': 118, 'end': 145, 'text': 'co-writer of the screenplay', 'document_ids': ['doc_0']}\n", - "{'start': 148, 'end': 159, 'text': 'Mary Parent', 'document_ids': ['doc_1']}\n", - "{'start': 164, 'end': 175, 'text': 'Cale Boyter', 'document_ids': ['doc_1']}\n", - "{'start': 177, 'end': 186, 'text': 'producers', 'document_ids': ['doc_1']}\n", - "{'start': 190, 'end': 204, 'text': 'Tanya Lapointe', 'document_ids': ['doc_1']}\n", - "{'start': 206, 'end': 219, 'text': 'Brian Herbert', 'document_ids': ['doc_1']}\n", - "{'start': 221, 'end': 234, 'text': 'Byron Merritt', 'document_ids': ['doc_1']}\n", - "{'start': 236, 'end': 247, 'text': 'Kim Herbert', 'document_ids': ['doc_1']}\n", - "{'start': 249, 'end': 260, 'text': 'Thomas Tull', 'document_ids': ['doc_1']}\n", - "{'start': 262, 'end': 283, 'text': 'Richard P. Rubinstein', 'document_ids': ['doc_1']}\n", - "{'start': 285, 'end': 298, 'text': 'John Harrison', 'document_ids': ['doc_1']}\n", - "{'start': 300, 'end': 315, 'text': 'Herbert W. Gain', 'document_ids': ['doc_1']}\n", - "{'start': 320, 'end': 337, 'text': 'Kevin J. Anderson', 'document_ids': ['doc_1']}\n", - "{'start': 339, 'end': 358, 'text': 'executive producers', 'document_ids': ['doc_1']}\n", - "{'start': 362, 'end': 372, 'text': 'Joe Walker', 'document_ids': ['doc_2']}\n", - "{'start': 374, 'end': 380, 'text': 'editor', 'document_ids': ['doc_2']}\n", - "{'start': 383, 'end': 393, 'text': 'Brad Riker', 'document_ids': ['doc_2']}\n", - "{'start': 395, 'end': 419, 'text': 'supervising art director', 'document_ids': ['doc_2']}\n", - "{'start': 422, 'end': 438, 'text': 'Patrice Vermette', 'document_ids': ['doc_2']}\n", - "{'start': 440, 'end': 459, 'text': 'production designer', 'document_ids': ['doc_2']}\n", - "{'start': 462, 'end': 474, 'text': 'Paul Lambert', 'document_ids': ['doc_2']}\n", - "{'start': 476, 'end': 501, 'text': 'visual effects supervisor', 'document_ids': ['doc_2']}\n", - "{'start': 504, 'end': 515, 'text': 'Gerd Nefzer', 'document_ids': ['doc_2']}\n", - "{'start': 517, 'end': 543, 'text': 'special effects supervisor', 'document_ids': ['doc_2']}\n", - "{'start': 546, 'end': 562, 'text': 'Thomas Struthers', 'document_ids': ['doc_2']}\n", - "{'start': 564, 'end': 582, 'text': 'stunt coordinator.', 'document_ids': ['doc_2']}\n", - "{'start': 686, 'end': 691, 'text': '2024.', 'document_ids': ['doc_0']}\n" - ] - } - ], - "source": [ - "print(\"Citations that support the final answer:\")\n", - "for cite in response.citations:\n", - " print(cite)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the top 3 chunks after rerank: \n", + "== Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\n", + "== stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\n", + "== series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\n" + ] + } + ], + "source": [ + "response = co.rerank(\n", + " query=query,\n", + " documents=top_chunks_after_retrieval,\n", + " top_n=3,\n", + " model=\"rerank-english-v2.0\",\n", + ")\n", + "\n", + "top_chunks_after_rerank = [result.document['text'] for result in response]\n", + "print(\"Here are the top 3 chunks after rerank: \")\n", + "for t in top_chunks_after_rerank:\n", + " print(\"== \" + t)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KuPL0VUXgbOt" + }, + "source": [ + "## Step 3 - Generate the model final answer, given the retrieved and reranked chunks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "oCNXWH8GgbOt" + }, + "outputs": [], + "source": [ + "# preamble containing instructions about the task and the desired style for the output.\n", + "preamble = \"\"\"\n", + "## Task & Context\n", + "You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n", + "\n", + "## Style Guide\n", + "Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "BevatShtgbOt", + "outputId": "af71f4a9-787a-4ee3-9598-20692fb3bf16" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "IueXaIJggbOu", - "outputId": "c816af51-74be-42c9-e94e-9820bbf95f79" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Here are the key crew members involved in 'Dune: Part Two':\n", - "\n", - "- **Denis Villeneuve**[1]: **director and producer**[1]\n", - "- **Jon Spaihts**[1]: **co-writer of the screenplay**[1]\n", - "- **Mary Parent**[2] and **Cale Boyter**[2]: **producers**[2] \n", - "- **Tanya Lapointe**[2], **Brian Herbert**[2], **Byron Merritt**[2], **Kim Herbert**[2], **Thomas Tull**[2], **Richard P. Rubinstein**[2], **John Harrison**[2], **Herbert W. Gain**[2] and **Kevin J. Anderson**[2]: **executive producers**[2] \n", - "- **Joe Walker**[3]: **editor**[3]\n", - "- **Brad Riker**[3]: **supervising art director**[3]\n", - "- **Patrice Vermette**[3]: **production designer**[3]\n", - "- **Paul Lambert**[3]: **visual effects supervisor**[3]\n", - "- **Gerd Nefzer**[3]: **special effects supervisor**[3]\n", - "- **Thomas Struthers**[3]: **stunt coordinator.**[3] \n", - "\n", - "A number of crew members from the first film returned for the sequel, which is set to be released in **2024.**[1]\n", - "\n", - "[1] source: \"Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\"\n", - "[2] source: \"stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\"\n", - "[3] source: \"series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\"\n" - ] - } - ], - "source": [ - "def insert_citations_in_order(text, citations):\n", - " \"\"\"\n", - " A helper function to pretty print citations.\n", - " \"\"\"\n", - " offset = 0\n", - " document_id_to_number = {}\n", - " citation_number = 0\n", - " modified_citations = []\n", - "\n", - " # Process citations, assigning numbers based on unique document_ids\n", - " for citation in citations:\n", - " citation_numbers = []\n", - " for document_id in sorted(citation[\"document_ids\"]):\n", - " if document_id not in document_id_to_number:\n", - " citation_number += 1 # Increment for a new document_id\n", - " document_id_to_number[document_id] = citation_number\n", - " citation_numbers.append(document_id_to_number[document_id])\n", - "\n", - " # Adjust start/end with offset\n", - " start, end = citation['start'] + offset, citation['end'] + offset\n", - " placeholder = ''.join([f'[{number}]' for number in citation_numbers])\n", - " # Bold the cited text and append the placeholder\n", - " modification = f'**{text[start:end]}**{placeholder}'\n", - " # Replace the cited text with its bolded version + placeholder\n", - " text = text[:start] + modification + text[end:]\n", - " # Update the offset for subsequent replacements\n", - " offset += len(modification) - (end - start)\n", - "\n", - " # Prepare citations for listing at the bottom, ensuring unique document_ids are listed once\n", - " unique_citations = {number: doc_id for doc_id, number in document_id_to_number.items()}\n", - " citation_list = '\\n'.join([f'[{doc_id}] source: \"{documents[doc_id - 1][\"snippet\"]}\"' for doc_id, number in sorted(unique_citations.items(), key=lambda item: item[1])])\n", - " text_with_citations = f'{text}\\n\\n{citation_list}'\n", - "\n", - " return text_with_citations\n", - "\n", - "\n", - "print(insert_citations_in_order(response.text, response.citations))\n" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Final answer:\n", + "Here are the key crew members involved in 'Dune: Part Two':\n", + "\n", + "- Denis Villeneuve: director and producer\n", + "- Jon Spaihts: co-writer of the screenplay\n", + "- Mary Parent and Cale Boyter: producers \n", + "- Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Richard P. Rubinstein, John Harrison, Herbert W. Gain and Kevin J. Anderson: executive producers \n", + "- Joe Walker: editor\n", + "- Brad Riker: supervising art director\n", + "- Patrice Vermette: production designer\n", + "- Paul Lambert: visual effects supervisor\n", + "- Gerd Nefzer: special effects supervisor\n", + "- Thomas Struthers: stunt coordinator. \n", + "\n", + "A number of crew members from the first film returned for the sequel, which is set to be released in 2024.\n" + ] + } + ], + "source": [ + "# retrieved documents\n", + "documents = [\n", + " {\"title\": \"chunk 0\", \"snippet\": top_chunks_after_rerank[0]},\n", + " {\"title\": \"chunk 1\", \"snippet\": top_chunks_after_rerank[1]},\n", + " {\"title\": \"chunk 2\", \"snippet\": top_chunks_after_rerank[2]},\n", + " ]\n", + "\n", + "# get model response\n", + "response = co.chat(\n", + " message=query,\n", + " documents=documents,\n", + " preamble=preamble,\n", + " model=\"command-r\",\n", + " temperature=0.3\n", + ")\n", + "\n", + "print(\"Final answer:\")\n", + "print(response.text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "20wcn-EjlXZd" + }, + "source": [ + "Note: this is indeed the answer you'd expect, and here was the passage of text in wikipedia explaining it!\n", + "\n", + "\" [...] Dune: Part Two was originally scheduled to be released on October 20, 2023, but was delayed to November 17, 2023, before moving forward two weeks to November 3, 2023, to adjust to changes in release schedules from other studios. It was later postponed by over four months to March 15, 2024, due to the 2023 Hollywood labor disputes. After the strikes were resolved, the film moved once more up two weeks to March 1, 2024. [...]\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RoSVDXSsgbOt" + }, + "source": [ + "## Bonus: Citations come for free with Cohere! 🎉\n", + "\n", + "At Cohere, all RAG calls come with... precise citations! 🎉\n", + "The model cites which groups of words, in the RAG chunks, were used to generate the final answer. \n", + "These citations make it easy to check where the model’s generated response claims are coming from. \n", + "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", + "These citations are optional — you can decide to ignore them.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "BVTuQdmDgbOt", + "outputId": "f843b262-d8bb-45ba-cbfb-9915da104eda" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Kp4c_HkYIEn_" - }, - "outputs": [], - "source": [] + "name": "stdout", + "output_type": "stream", + "text": [ + "Citations that support the final answer:\n", + "{'start': 63, 'end': 79, 'text': 'Denis Villeneuve', 'document_ids': ['doc_0']}\n", + "{'start': 81, 'end': 102, 'text': 'director and producer', 'document_ids': ['doc_0']}\n", + "{'start': 105, 'end': 116, 'text': 'Jon Spaihts', 'document_ids': ['doc_0']}\n", + "{'start': 118, 'end': 145, 'text': 'co-writer of the screenplay', 'document_ids': ['doc_0']}\n", + "{'start': 148, 'end': 159, 'text': 'Mary Parent', 'document_ids': ['doc_1']}\n", + "{'start': 164, 'end': 175, 'text': 'Cale Boyter', 'document_ids': ['doc_1']}\n", + "{'start': 177, 'end': 186, 'text': 'producers', 'document_ids': ['doc_1']}\n", + "{'start': 190, 'end': 204, 'text': 'Tanya Lapointe', 'document_ids': ['doc_1']}\n", + "{'start': 206, 'end': 219, 'text': 'Brian Herbert', 'document_ids': ['doc_1']}\n", + "{'start': 221, 'end': 234, 'text': 'Byron Merritt', 'document_ids': ['doc_1']}\n", + "{'start': 236, 'end': 247, 'text': 'Kim Herbert', 'document_ids': ['doc_1']}\n", + "{'start': 249, 'end': 260, 'text': 'Thomas Tull', 'document_ids': ['doc_1']}\n", + "{'start': 262, 'end': 283, 'text': 'Richard P. Rubinstein', 'document_ids': ['doc_1']}\n", + "{'start': 285, 'end': 298, 'text': 'John Harrison', 'document_ids': ['doc_1']}\n", + "{'start': 300, 'end': 315, 'text': 'Herbert W. Gain', 'document_ids': ['doc_1']}\n", + "{'start': 320, 'end': 337, 'text': 'Kevin J. Anderson', 'document_ids': ['doc_1']}\n", + "{'start': 339, 'end': 358, 'text': 'executive producers', 'document_ids': ['doc_1']}\n", + "{'start': 362, 'end': 372, 'text': 'Joe Walker', 'document_ids': ['doc_2']}\n", + "{'start': 374, 'end': 380, 'text': 'editor', 'document_ids': ['doc_2']}\n", + "{'start': 383, 'end': 393, 'text': 'Brad Riker', 'document_ids': ['doc_2']}\n", + "{'start': 395, 'end': 419, 'text': 'supervising art director', 'document_ids': ['doc_2']}\n", + "{'start': 422, 'end': 438, 'text': 'Patrice Vermette', 'document_ids': ['doc_2']}\n", + "{'start': 440, 'end': 459, 'text': 'production designer', 'document_ids': ['doc_2']}\n", + "{'start': 462, 'end': 474, 'text': 'Paul Lambert', 'document_ids': ['doc_2']}\n", + "{'start': 476, 'end': 501, 'text': 'visual effects supervisor', 'document_ids': ['doc_2']}\n", + "{'start': 504, 'end': 515, 'text': 'Gerd Nefzer', 'document_ids': ['doc_2']}\n", + "{'start': 517, 'end': 543, 'text': 'special effects supervisor', 'document_ids': ['doc_2']}\n", + "{'start': 546, 'end': 562, 'text': 'Thomas Struthers', 'document_ids': ['doc_2']}\n", + "{'start': 564, 'end': 582, 'text': 'stunt coordinator.', 'document_ids': ['doc_2']}\n", + "{'start': 686, 'end': 691, 'text': '2024.', 'document_ids': ['doc_0']}\n" + ] } - ], - "metadata": { + ], + "source": [ + "print(\"Citations that support the final answer:\")\n", + "for cite in response.citations:\n", + " print(cite)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "hackathon_docs_3", - "language": "python", - "name": "python3" + "base_uri": "https://localhost:8080/" }, - "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" + "id": "IueXaIJggbOu", + "outputId": "c816af51-74be-42c9-e94e-9820bbf95f79" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the key crew members involved in 'Dune: Part Two':\n", + "\n", + "- **Denis Villeneuve**[1]: **director and producer**[1]\n", + "- **Jon Spaihts**[1]: **co-writer of the screenplay**[1]\n", + "- **Mary Parent**[2] and **Cale Boyter**[2]: **producers**[2] \n", + "- **Tanya Lapointe**[2], **Brian Herbert**[2], **Byron Merritt**[2], **Kim Herbert**[2], **Thomas Tull**[2], **Richard P. Rubinstein**[2], **John Harrison**[2], **Herbert W. Gain**[2] and **Kevin J. Anderson**[2]: **executive producers**[2] \n", + "- **Joe Walker**[3]: **editor**[3]\n", + "- **Brad Riker**[3]: **supervising art director**[3]\n", + "- **Patrice Vermette**[3]: **production designer**[3]\n", + "- **Paul Lambert**[3]: **visual effects supervisor**[3]\n", + "- **Gerd Nefzer**[3]: **special effects supervisor**[3]\n", + "- **Thomas Struthers**[3]: **stunt coordinator.**[3] \n", + "\n", + "A number of crew members from the first film returned for the sequel, which is set to be released in **2024.**[1]\n", + "\n", + "[1] source: \"Dune: Part Two is a 2024 American epic science fiction film directed and produced by Denis Villeneuve, who co-wrote the screenplay with Jon Spaihts. The sequel to Dune (2021) adapts the 1965 novel Dune by Frank Herbert and follows Paul Atreides as he unites with the Fremen people of the desert planet Arrakis to wage war against House Harkonnen. Timothée Chalamet, Rebecca Ferguson, Josh Brolin, Stellan Skarsgård, Dave Bautista, Zendaya, Charlotte Rampling, and Javier Bardem reprise their roles from the first\"\n", + "[2] source: \"stunt coordinator. Dune: Part Two was produced by Villeneuve, Mary Parent, and Cale Boyter, with Tanya Lapointe, Brian Herbert, Byron Merritt, Kim Herbert, Thomas Tull, Jon Spaihts, Richard P. Rubinstein, John Harrison, and Herbert W. Gain serving as executive producers and Kevin J. Anderson as creative consultant. Legendary CEO Joshua Grode confirmed in April 2019 that they plan to make a sequel, adding that \"there's a logical place to stop the [first] movie before the book is over\".In December 2020,\"\n", + "[3] source: \"series. Villeneuve ultimately secured a two-film deal with Warner Bros. Pictures, in the same style as the two-part adaption of Stephen King's It in 2017 and 2019. In January 2019, Joe Walker was confirmed to be serving as the film's editor. Other crew included Brad Riker as supervising art director, Patrice Vermette as production designer, Paul Lambert as visual effects supervisor, Gerd Nefzer as special effects supervisor, and Thomas Struthers as stunt coordinator. Dune: Part Two was produced by\"\n" + ] } + ], + "source": [ + "def insert_citations_in_order(text, citations):\n", + " \"\"\"\n", + " A helper function to pretty print citations.\n", + " \"\"\"\n", + " offset = 0\n", + " document_id_to_number = {}\n", + " citation_number = 0\n", + " modified_citations = []\n", + "\n", + " # Process citations, assigning numbers based on unique document_ids\n", + " for citation in citations:\n", + " citation_numbers = []\n", + " for document_id in sorted(citation[\"document_ids\"]):\n", + " if document_id not in document_id_to_number:\n", + " citation_number += 1 # Increment for a new document_id\n", + " document_id_to_number[document_id] = citation_number\n", + " citation_numbers.append(document_id_to_number[document_id])\n", + "\n", + " # Adjust start/end with offset\n", + " start, end = citation['start'] + offset, citation['end'] + offset\n", + " placeholder = ''.join([f'[{number}]' for number in citation_numbers])\n", + " # Bold the cited text and append the placeholder\n", + " modification = f'**{text[start:end]}**{placeholder}'\n", + " # Replace the cited text with its bolded version + placeholder\n", + " text = text[:start] + modification + text[end:]\n", + " # Update the offset for subsequent replacements\n", + " offset += len(modification) - (end - start)\n", + "\n", + " # Prepare citations for listing at the bottom, ensuring unique document_ids are listed once\n", + " unique_citations = {number: doc_id for doc_id, number in document_id_to_number.items()}\n", + " citation_list = '\\n'.join([f'[{doc_id}] source: \"{documents[doc_id - 1][\"snippet\"]}\"' for doc_id, number in sorted(unique_citations.items(), key=lambda item: item[1])])\n", + " text_with_citations = f'{text}\\n\\n{citation_list}'\n", + "\n", + " return text_with_citations\n", + "\n", + "\n", + "print(insert_citations_in_order(response.text, response.citations))\n" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/Wikipedia_Semantic_Search_With_Cohere_Embeddings_Archives.ipynb b/notebooks/Wikipedia_Semantic_Search_With_Cohere_Embeddings_Archives.ipynb index ad762fb3..d8cfbf9b 100644 --- a/notebooks/Wikipedia_Semantic_Search_With_Cohere_Embeddings_Archives.ipynb +++ b/notebooks/Wikipedia_Semantic_Search_With_Cohere_Embeddings_Archives.ipynb @@ -10,19 +10,6 @@ "This notebook contains the starter code to do simple [semantic search](https://txt.cohere.ai/what-is-semantic-search/) on the [Wikipedia embeddings archives](https://txt.cohere.ai/embedding-archives-wikipedia/) published by Cohere. These archives embed Wikipedia sites in multiple languages. In this example, we'll use [Wikipedia Simple English](https://huggingface.co/datasets/Cohere/wikipedia-22-12-simple-embeddings). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "IUnwp2cYNnP0" - }, - "outputs": [], - "source": [ - "# Let's install \"cohere<5\" and HF datasets\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" datasets" - ] - }, { "cell_type": "markdown", "metadata": { @@ -207,7 +194,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/agents/Data_Analyst_Agent_Cohere_and_Langchain.ipynb b/notebooks/agents/Data_Analyst_Agent_Cohere_and_Langchain.ipynb index 3fcf1cfa..efeb595d 100644 --- a/notebooks/agents/Data_Analyst_Agent_Cohere_and_Langchain.ipynb +++ b/notebooks/agents/Data_Analyst_Agent_Cohere_and_Langchain.ipynb @@ -17,7 +17,7 @@ "source": [ "# Tool Use - Simple Data Analyst Agent with Cohere and Langchain\n", "\n", - "Tool use is a method whichs allows developers to connect Cohere's Command models to external tools like search engines, APIs, databases, and other software tools. Just like how [Retrieval-Augmented Generation (RAG)](https://docs.cohere.com/docs/retrieval-augmented-generation-rag) allows a model to use an external data source to improve factual generation, tool use is a capability that allows retrieving data from multiple sources. But it goes beyond simply retrieving information and is able to use software tools to execute code, or even create entries in a CRM system.\n", + "Tool use is a method which allows developers to connect Cohere's Command models to external tools like search engines, APIs, databases, and other software tools. Just like how [Retrieval-Augmented Generation (RAG)](https://docs.cohere.com/docs/retrieval-augmented-generation-rag) allows a model to use an external data source to improve factual generation, tool use is a capability that allows retrieving data from multiple sources. But it goes beyond simply retrieving information and is able to use software tools to execute code, or even create entries in a CRM system.\n", "\n", "In this notebook, we'll see how we can use two tools to create a simple data analyst agent that is able to search the web and run code in a python interpreter. This agent uses Cohere's Command R+ mode and Langchain.\n", "\n", @@ -92,7 +92,7 @@ }, "source": [ "### Web search\n", - "Let's first equip our agent with web search! We can use the Tivaly API for this. Head on to [tavily.com](https://tavily.com) and grab an API key to use here." + "Let's first equip our agent with web search! We can use the Tavily API for this. Head on to [tavily.com](https://tavily.com) and grab an API key to use here." ] }, { @@ -390,7 +390,7 @@ "id": "wZBaxCYeG4Xf" }, "source": [ - "This is a simple example to get you start. There [are many tools](https://python.langchain.com/docs/integrations/tools/) you can equip your agent with. Once youre comfortable with these ideas, you can also proceed to define your tools (see [Multi-step tool use in Action](https://docs.cohere.com/docs/multi-step-tool-use#multi-step-tool-use-in-action)).\n" + "This is a simple example to get you started. There [are many tools](https://python.langchain.com/docs/integrations/tools/) you can equip your agent with. Once you're comfortable with these ideas, you can also proceed to define your tools (see [Multi-step tool use in Action](https://docs.cohere.com/docs/multi-step-tool-use#multi-step-tool-use-in-action)).\n" ] } ], @@ -413,7 +413,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/agents/Financial_Analyst_Agent_with_Custom_API_Tool.ipynb b/notebooks/agents/Financial_Analyst_Agent_with_Custom_API_Tool.ipynb new file mode 100644 index 00000000..c497a747 --- /dev/null +++ b/notebooks/agents/Financial_Analyst_Agent_with_Custom_API_Tool.ipynb @@ -0,0 +1,669 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "EUYMLmXAF3W1" + }, + "source": [ + "# A ReAct Agent with Command R+, Integrating a Custom API Tool for Financial Analysis\n", + "\n", + "Adaptive RAG is a strategy for RAG that unites (1) [query analysis](https://blog.langchain.dev/query-construction/) with (2) [active / self-corrective RAG](https://blog.langchain.dev/agentic-rag-with-langgraph/).\n", + "\n", + "In the paper, they report query analysis to route across:\n", + "- No Retrieval (LLM answers)\n", + "- Single-shot RAG\n", + "- Iterative RAG\n", + "\n", + "\n", + "We'll use Command R+, a recent release from Cohere that:\n", + "- Has strong accuracy on RAG, Tool Use and Agents\n", + "- Has 128k context\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W8yvOB2MQp07" + }, + "source": [ + "# Environment" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ujQVUvA9QlD4", + "outputId": "230c6a56-3ee3-4e0d-95af-2a261b8541d6" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install --quiet langchain langchain_cohere tiktoken faiss-cpu beautifulsoup4 langchain_experimental matplotlib tabulate python-dotenv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save your credentials in a .env file in your user root directory, so that you can retrieve securely" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from dotenv import load_dotenv\n", + "load_dotenv()\n", + "\n", + "COHERE_API_KEY = os.environ.get(\"COHERE_API_KEY\")\n", + "TAVILY_API_KEY = os.environ.get(\"TAVILY_API_KEY\") # Get your Free API key at https://app.tavily.com once you sign up\n", + "FMP_API_KEY = os.environ.get(\"FMP_API_KEY\") # Get your Free API key https://site.financialmodelingprep.com/ once you sign up" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "k3mrKxSsTfXO" + }, + "source": [ + "# Create tools\n", + "The ReAct agent will be equipped with these tools. The model can pick between\n", + "- web search\n", + "- RAG: retrieval from a vector store\n", + "- custom tool (call an external API)\n", + "- directly answering\n", + "\n", + "The model can use any of these tools, in any sequence of steps, and self-reflect." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4kGUB4IRF3W5" + }, + "source": [ + "### Web search tool" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "hYsJgVY0F3W5" + }, + "outputs": [], + "source": [ + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "internet_search = TavilySearchResults()\n", + "internet_search.name = \"internet_search\"\n", + "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", + "\n", + "\n", + "class TavilySearchInput(BaseModel):\n", + " query: str = Field(description=\"Query to search the internet with\")\n", + "\n", + "\n", + "internet_search.args_schema = TavilySearchInput" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Python interpreter tool" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.agents import Tool\n", + "from langchain_experimental.utilities import PythonREPL\n", + "\n", + "python_repl = PythonREPL()\n", + "repl_tool = Tool(\n", + " name=\"python_repl\",\n", + " description=\"Executes python code and returns the result. The code runs in a static sandbox without interactive mode, so print output or save output to a file.\",\n", + " func=python_repl.run,\n", + ")\n", + "repl_tool.name = \"python_interpreter\"\n", + "\n", + "# from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class ToolInput(BaseModel):\n", + " code: str = Field(description=\"Python code to execute.\")\n", + "repl_tool.args_schema = ToolInput" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NxDa_Em0tuas" + }, + "source": [ + "### RAG tool" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "0QyahrNPtwEi" + }, + "outputs": [], + "source": [ + "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", + "from langchain_cohere import CohereEmbeddings\n", + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import FAISS\n", + "\n", + "# Set embeddings\n", + "embd = CohereEmbeddings()\n", + "\n", + "# Docs to index\n", + "urls = [\n", + " \"https://www.mayerbrown.com/en/insights/publications/2023/03/new-data-standards-pending-for-federally-regulated-financial-entities\",\n", + " \"https://plaid.com/resources/open-finance/what-is-fdx/\",\n", + " \"https://www.egnyte.com/guides/financial-services/financial-data-compliance\",\n", + "]\n", + "\n", + "# Load\n", + "docs = [WebBaseLoader(url).load() for url in urls]\n", + "docs_list = [item for sublist in docs for item in sublist]\n", + "\n", + "# Split\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=512, chunk_overlap=0\n", + ")\n", + "doc_splits = text_splitter.split_documents(docs_list)\n", + "\n", + "# Add to vectorstore\n", + "vectorstore = FAISS.from_documents(\n", + " documents=doc_splits,\n", + " embedding=embd,\n", + ")\n", + "\n", + "vectorstore_retriever = vectorstore.as_retriever()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "eoa3toXfdGkI" + }, + "outputs": [], + "source": [ + "from langchain.tools.retriever import create_retriever_tool\n", + "\n", + "vectorstore_search = create_retriever_tool(\n", + " retriever=vectorstore_retriever,\n", + " name=\"vectorstore_search\",\n", + " description=\"Retrieve relevant info from a vectorstore that contains documents related to Data Compliance for Financial Services and its regulation.\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Custom Tool For Market Capitalization\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. Define the function" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "\n", + "# Function to get the market capitalization of a ticker symbol\n", + "def get_market_cap(ticker):\n", + " url = f\"https://financialmodelingprep.com/api/v3/market-capitalization/{ticker}?apikey={FMP_API_KEY}\"\n", + " response = requests.get(url)\n", + " if response.status_code == 200:\n", + " data = response.json()\n", + " if data and isinstance(data, list) and len(data) > 0:\n", + " market_cap = data[0].get('marketCap', 'No market cap data available')\n", + " return [{'id': 0, 'text': f'Market cap for {ticker}: ${market_cap}'}]\n", + " else:\n", + " return \"No data available for the specified ticker.\"\n", + " else:\n", + " return \"Failed to retrieve data from the API.\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Define the Custom Tool" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.tools import tool\n", + "\n", + "@tool\n", + "def market_cap(ticker: str) -> list:\n", + " \"\"\"This tool is only used to find market capitalization. Do not use it for anything else. Find the ticker when asked about capitalization. The ticker symbol of the company (e.g., AAPL which is the ticker for Apple Inc, MSFT for Microsoft )\"\"\"\n", + " return get_market_cap(ticker)\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2ENQAfYXRG9Q" + }, + "source": [ + "# Create the ReAct Agent\n", + "The model can smartly pick the right tool(s) for the user query, call them in any sequence of steps, analyze the results and self-reflect." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "hx-Ew1i5F3W4" + }, + "outputs": [], + "source": [ + "from langchain.agents import AgentExecutor\n", + "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", + "from langchain_core.prompts import ChatPromptTemplate" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "BPo3ZIHkF3W4" + }, + "outputs": [], + "source": [ + "# LLM\n", + "from langchain_cohere.chat_models import ChatCohere\n", + "\n", + "chat = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"\n", + "Use all tools that are available to answear the question. \n", + "If the query covers the topics of Federal Financial Institutions, use the vectorstore search first.\n", + "If the query covers market capitalization, use the market cap tool first.\n", + "You are equipped with an internet search tool, and python interpreter, a market cap api, and a special vectorstore of information about Data Compliance for Financial Services.\n", + "\n", + "\"\"\"\n", + "\n", + "# Prompt\n", + "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", + "\n", + "# Create the ReAct agent\n", + "agent = create_cohere_react_agent(\n", + " llm=chat,\n", + " tools=[vectorstore_search, internet_search, repl_tool, market_cap],\n", + " prompt=prompt,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "dks-7TGGtdLE" + }, + "outputs": [], + "source": [ + "agent_executor = AgentExecutor(\n", + " agent=agent, tools=[vectorstore_search, internet_search, repl_tool, market_cap], verbose=True\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v7L1aBHds1pj" + }, + "source": [ + "# Testing the ReAct agent" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ibo31dsHEjPv" + }, + "source": [ + "**Let's ask a question that requires web search.**" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "AW_8C7mszsVE", + "outputId": "9be7067f-a776-4688-8864-db873d1fb65a" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for how the current interest rate environment affects the bond market.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'How does the current interest rate environment affect the bond market?'}}\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m[{'url': 'https://www.morningstar.com/bonds/how-do-interest-rates-affect-your-bonds', 'content': \"The federal-funds rate, the interest rate at which banks lend money to each other overnight, is now targeted between 1.75% and 2.00%. When the Fed raises or lowers rates, it affects bonds' prices ...\"}, {'url': 'https://www.usbank.com/investing/financial-perspectives/market-news/interest-rates-affect-bonds.html', 'content': 'Personal\\nBank accounts\\nCredit cards\\nInvesting and retirement\\nPersonal loans & lines\\nHome loans\\nVehicle loans\\nMobile and online\\nExplore personal banking\\nWealth Management\\nOur services\\nInvesting\\nYour goals\\nAdvisors & wealth teams\\nPrivate Wealth Management\\nOur perspectives\\nExplore Wealth Management\\nBusiness\\nExplore business banking\\nBusiness bank accounts\\nBusiness credit cards\\nBusiness loans and lines\\nBusiness services\\nBusiness payments\\nBusiness industry expertise\\nExplore business resources\\nOnline & mobile banking\\nCorporate & Commercial\\nExplore Even after the recent yield decline, year-to-date total returns reflect a gain of 4.2% according to the Bloomberg U.S. Aggregate Bond Index through mid-December 2023.3\\nInverted yield curve persists\\nA phenomenon that developed in 2022 and continues in 2023 is the unusual shape of the yield curve representing different bond maturities. The Fed sought to slow the economy as a way to reduce inflation, which peaked at 9.1% for the 12 months ending June 2022, but dropped to less than 3.1% by November 2023.2\\nWhat should investors expect from the bond market in 2024 and what does that say about how to incorporate or adjust strategies for fixed-income portfolios?\\n Article\\nHow changing interest rates impact the bond market\\nDecember 18, 2023\\nWebinar\\n2024 Investment Outlook – Jan. 24\\nExploring the impact of today’s interest rates and the 2024 presidential election on your investments.\\n In fact, the economy generated solid growth as measured by Gross Domestic Product (GDP) and surprised many forecasters by expanding at an annualized rate of 5.2% in the third quarter of 2023.4\\nKeeping an eye on the Fed\\nThe Fed remains focused on fighting inflation but may be about to modify its interest rate policy.'}, {'url': 'https://investor.vanguard.com/investor-resources-education/news/the-dynamics-of-bond-duration-and-rising-rates', 'content': \"When the investment horizon is longer than the bond's duration, however, higher yields on reinvested cash flow outweigh the market price decline. Over a period of 15, 20, or 25 years, interest rate rises of 100 and 200 basis points result in an improvement in total returns. (The inverse is true for total returns when interest rates decline.\"}, {'url': 'https://www.investopedia.com/articles/bonds/09/bond-market-interest-rates.asp', 'content': \"Interest rate risk is the risk of changes in a bond's price due to changes in prevailing interest rates. Changes in short-term versus long-term interest rates can affect various bonds in different ...\"}, {'url': 'https://investor.vanguard.com/investor-resources-education/article/how-rising-interest-rates-affect-bond-funds', 'content': \"Most of the time it's lower because SEC yield reflects fund fees.2\\xa0Given these dynamics, it’s helpful to look to the SEC yield as a reasonable forward-looking picture of the current income of the fund, based on current market value.\\n… and distribution yield\\nThen there’s a bond fund’s distribution yield, which is important because it reflects what the fund’s monthly distributions are.3\\nThe challenge is that VGSH's distribution yield as of May 31, 2022, was 0.57%—well below both the 2.53% that individual 2-year notes were yielding and the 2.53% SEC yield as of that date. (The average effective maturity and the average duration of VGSH were 1.9 years and 2.0\\nYield measure\\nVGSH SEC yield\\nOctober 2021\\n0.34%\\nMay 2022\\n2.53%\\nImpact of rising rates on yield metrics\\nChanges in the SEC yield for VGSH typically follow the YTM because of the nature of the calculation. Yield measure\\nVGSH YTM\\nOctober 2021\\n0.49%\\nMay 2022\\n2.48%\\nImpact of rising rates on yield metrics\\nThe yield to maturity (YTM) for VGSH closely tracks the 2-year Treasury yield given the proximity of the fund’s overall composition to the 2-year key rate. Yield measure\\nVGSH distribution yield\\nOctober 2021\\n0.28%\\nMay 2022\\n0.57%\\nImpact of rising rates on yield metrics\\nThe yield measure that lags most, the ETF’s distribution yield, hasn’t yet caught up with the rise in rates. More broadly, the Bloomberg U.S. Aggregate Float Adjusted Bond Index fell by as much as 12.7% year-to-date through June 14, 2022—the most it’s lost in this short a time in 40 years.1\\nTreasury yield curve change from year-end 2021 to end of 2022\\nNote:\\xa0Data includes the rate hike in December 2022 and subsequent market reaction.\\n\"}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4\n", + "Cited Documents: 0,1,2,3,4\n", + "Answer: Interest rates have a direct impact on bond prices. When interest rates rise, bond prices fall, and vice versa. The federal-funds rate, the interest rate at which banks lend money to each other overnight, is now targeted between 1.75% and 2.00%. The Fed sought to slow the economy as a way to reduce inflation, which peaked at 9.1% for the 12 months ending June 2022, but dropped to less than 3.1% by November 2023.\n", + "Grounded answer: Interest rates have a direct impact on bond prices. When interest rates rise, bond prices fall, and vice versa. The federal-funds rate, the interest rate at which banks lend money to each other overnight, is now targeted between 1.75% and 2.00%. The Fed sought to slow the economy as a way to reduce inflation, which peaked at 9.1% for the 12 months ending June 2022, but dropped to less than 3.1% by November 2023.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + } + ], + "source": [ + "result = agent_executor.invoke(\n", + " {\n", + " \"input\": \"How does the current interest rate environment affect the bond market?\",\n", + " \"preamble\": preamble,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Interest rates have a direct impact on bond prices. When interest rates rise, bond prices fall, and vice versa. The federal-funds rate, the interest rate at which banks lend money to each other overnight, is now targeted between 1.75% and 2.00%. The Fed sought to slow the economy as a way to reduce inflation, which peaked at 9.1% for the 12 months ending June 2022, but dropped to less than 3.1% by November 2023.'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[\"output\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lKkxSvJmEn8Z" + }, + "source": [ + "**Let's ask a question that requires RAG retrieval from the vector db.**" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Jl0JNX2TF3W5", + "outputId": "2ccb747c-e702-4473-f587-47271e0c71b2" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for the primary functions of the Federal Financial Institutions Examination Council (FFIEC) in the vector store.\n", + "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'primary functions of the Federal Financial Institutions Examination Council (FFIEC)?'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3mlosses and improve overall cybersecurity by implementing best practices and employing proven cybersecurity frameworks. The importance of financial data compliance continues to grow as regulations continue to expand globally to ensure that customers’ personal information and finances are protected from theft and fraud.Advantages of Financial Data Compliance and Cost of Non-ComplianceBenefits of financial data complianceNot following financial data complianceView of the most critical data and systemsPlan for cybersecurity tools and practicesProtection of valuable informationRapid response to cybersecurity incidentsOperational disruptionsReputational damageCivil and criminal lawsuitsFines and losses due to cybersecurity incidentsTop Five Data Compliances for Financial ServicesFive Most Important United States Drivers for Financial Data Compliance1. Commodities Future Trading Commission (CFTC)The CFTC oversees the U.S. derivatives markets, including futures contracts, options, and over-the-counter (OTC) markets. While the rules that the CFTC has oversight of were part of the Commodities Exchange Act (CEA), which was passed in 1936, the Commission itself was established in 1974 by the passage of the Commodities Futures Trading Commission Act. The mission of the CFTC is to enforce laws, rules, and regulations within the derivatives markets it oversees to help ensure that firms and individuals operating in such markets provide legally required privacy rights to their consumers and promote the integrity, resilience, and vibrancy of the U.S. derivatives markets through sound regulation.2. Federal Deposit Insurance Corporation (FDIC)The FDIC provides deposit insurance of at least $250,000 for accounts with banks and thrift institutions. The FDIC aims to preserve and promote the public’s confidence in the U.S. financial system by providing deposit insurance. The FDIC is also responsible for enforcing financial data compliance as part of its mandate to ensure that banks comply with consumer data protection laws, including the Gramm-Leach-Bliley Act, which includes data security directives.3. Federal ReserveThe Federal Reserve Banking System provides guidance on managing outsourcing risk, including data for all financial institutions supervised by the Federal Reserve. It is also responsible for supervising, monitoring, inspecting, and examining institutions’ financial data compliance to ensure that they adhere to the necessary rules and regulations, including those published by the Federal Financial Institutions Examination Council (FFIEC) and Section 501 of the Gramm-Leach-Bliley Act (GLBA), regarding safeguards for customer data.4. Federal Financial Institutions Examination Council (FFIEC)The Federal Financial Institutions Examination\n", + "\n", + "Council is a five-member U.S. government interagency body. It consists of five banking regulators and is responsible for uniformity in the guidelines and supervision of financial institutions, including financial data compliance. It includes financial data management mandates, such as directing how organizations should govern the secure storage of all types of sensitive information, whether on computer systems, physical media, or hard-copy documents.5. Financial Industry Regulatory Authority (FINRA) SEC Rules 17a-4The Securities and Exchange Commission (SEC) requires broker-dealers to adhere to numerous financial data compliance regulations, including SEC Rule 17a-4(f)(3)(vii), which includes strict mandates on how electronic data must be stored, how it can be accessed, and how and when the archiving process should be reviewed. Several additional U.S. drivers for financial data compliance include the following:Dodd-Frank Wall Street Reform and Consumer Protection Act (Dodd-Frank)The Dodd-Frank Act was enacted in 2010 to facilitate financial stability by augmenting transparency and accountability. Financial data compliance requirements include specific directives related to email. To adhere to Dodd-Frank financial data compliance requirements related to communication, financial organizations must take steps to preserve email communication within proscribed periods of time with redundancy and other procedures to ensure that it is protected.  Office for the Comptroller of the Currency (OCC) The Office for the Comptroller of the Currency (OCC) is an independent bureau of the U.S. Department of the Treasury that charters, regulates, and supervises all national banks and federal savings associations, as well as federal branches and agencies of foreign banks. As part of its charter to protect consumers, the OCC enforces federal data compliance regulations, such as FFIEC, GLBA, and the Privacy Act of 1974.Securities Exchange Commission (SEC)The Securities Exchange Commission (SEC) protects investors by ensuring the maintenance of fair, orderly, and efficient markets and facilitating capital formation. The SEC Cybersecurity Rule 2023 requires that market entities (e.g., broker-dealers, national securities exchanges) establish, maintain, and enforce written policies and procedures that are reasonably designed to address their cybersecurity risks. With regard to financial data compliance, the SEC requires any data breach that compromises the confidentiality, integrity, or availability of an information asset.Sarbanes-Oxley Act (SOX)SOX focuses on how organizations disclose and record their financial information. Financial data compliance provisions dictate that organizations must install cybersecurity\n", + "\n", + "PartnersMSP ProgramTECHNOLOGY PARTNERSGoogle WorkspaceMicrosoft 365SalesforceAll Apps and IntegrationsDeveloper's Toolkit Login Start Free Trial Get DemoResourcesPRODUCT HELPUniversityHelp DeskADDITIONAL RESOURCESBlogResource CenterGuidesEventsCase Studies Login Start Free Trial Get DemoCompanyCOMPANYAbout UsCareersContact Us Login Start Free Trial Get DemoSolutionsUse CasesPartnersResourcesCompanyPricing Login Start Free Trial Get Demo Submitted by on Tue, 11/14/2023 - 06:23 Home> Guides> Financial Services> Data Compliance for Financial ServicesHome > Data Compliance for Financial ServicesData Compliance for Financial ServicesShare this PageLet’s jump in and learn:What Is Financial Compliance?Top Five Data Compliances for Financial ServicesExamples of the United Kingdom (U.K.) and European Union (E.U.) Drivers for Financial Data ComplianceWhy are Compliance Laws Important?Limitations of Compliance LawsTips for Complying with Data Security RegulationsFinancial Data Compliance Improves Overall SecurityWhat Is Financial Compliance?Financial compliance is financial institutions’ (e.g., financial services organizations, capital markets) adherence to internal and external rules set forth by governments, industry groups, and internal governance policies. Financial data compliance is a governance structure focused on data protection that ensures that an organization complies with laws, regulations, and standards around its data. Financial data compliance includes processes and security tools to govern and secure the possession, organization, storage, and management of digital assets or data to prevent loss, theft, misuse, or compromise. Different financial data compliance regulations specify the types of data that require protection and, in some cases, direct what should be done to ensure its security.The growing stringency of financial data compliance requirements also pushes organizations to rethink updating legacy security systems.Origin of Financial ComplianceThe term was first used by the Basel Committee on Banking Supervision (BCBS, the primary global standard setter for the prudential regulation of banks) in 2005. In its document “Compliance and the compliance function in banks,” the body defines compliance, “The expression compliance risk is defined in this paper as the risk of legal or regulatory sanctions, material financial loss, or loss to reputation a bank may suffer as a result of its failure to comply with laws, regulations, rules, related self-regulatory organization standards, and codes of conduct applicable to its banking activities.”Financial data compliance helps organizations prevent legal issues and financial\n", + "\n", + "to protect financial data.Sections 302 and 304 of SOX set standards for data protection. While SOX does not specify any specific controls to protect financial data, encryption is widely considered to be the best practice.SWIFT CSPSociety for Worldwide Interbank Financial Telecommunication (SWIFT) is a Belgian cooperative society providing services related to the execution of financial transactions and payments between banks worldwide. Financial organizations that use SWIFT services must comply with SWIFT Customer Security Program (CSP) requirements. The framework outlines requirements for data protection, access management, and incident response. The SWIFT Customer Security Controls Framework has three objectives with eight principles.1. Secure your environmentRestrict internet accessSegregate critical systems from general IT environmentsReduce attack surface and vulnerabilitiesPhysically secure the environment2. Know and limit access Prevent compromise of credentials Manage identities and segregate privilege3. Detect and respondDetect anomalous activity in systems or transactional recordsPlan for incident response and information sharingExamples of the United Kingdom (U.K.) and European Union (E.U.) Drivers for Financial Data ComplianceGeneral Data Protection Regulation (GDPR) GDPR is the primary law regulating how organizations protect E.U. citizens’ personal data, setting forth stringent financial data compliance requirements. Several of the financial data requirements for GDPR that impact financial institutions are:Individuals must give explicit consent for their personal data to be collected and used.Individuals must understand how their information is going to be used.Organizations must clearly stipulate the legal channels available should data processing not comply with its agreed-upon use.All personal data must be destroyed after a prescribed period of time.In the event of a serious cyberattack, organizations must inform all those affected by the security breach and the Information Commissioner’s Office within 72 hours.Markets in Financial Instruments Directive II (MiFID II)The primary objective of MiFID II is to enhance investor protection with increased transparency and reporting, enhanced governance rules, and heightened regulation of markets.Related to financial data compliance, MiFID II, banks, and financial firms must implement common data processes and data quality metrics, which requires the adoption of data standards to ensure consistency of reporting across all regulated activities. Financial institutions must also manage multiple identifiers, including industry standard Market Identifier Codes (MIC) and the Global Legal Entity Identifier (LEI) to meet financial data compliance requirements.Why are Compliance Laws Important?Financial\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "Cited Documents: 0\n", + "Answer: The Federal Financial Institutions Examination Council (FFIEC) is a five-member U.S. government interagency body, consisting of five banking regulators. It is responsible for uniformity in the guidelines and supervision of financial institutions, including financial data compliance. It includes financial data management mandates, such as directing how organisations should govern the secure storage of all types of sensitive information, whether on computer systems, physical media, or hard-copy documents.\n", + "Grounded answer: The Federal Financial Institutions Examination Council (FFIEC) is a five-member U.S. government interagency body, consisting of five banking regulators. It is responsible for uniformity in the guidelines and supervision of financial institutions, including financial data compliance. It includes financial data management mandates, such as directing how organisations should govern the secure storage of all types of sensitive information, whether on computer systems, physical media, or hard-copy documents.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + } + ], + "source": [ + "result = agent_executor.invoke(\n", + " {\n", + " \"input\": \"What are the primary functions of the Federal Financial Institutions Examination Council (FFIEC)?\",\n", + " \"preamble\": preamble,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'The Federal Financial Institutions Examination Council (FFIEC) is a five-member U.S. government interagency body, consisting of five banking regulators. It is responsible for uniformity in the guidelines and supervision of financial institutions, including financial data compliance. It includes financial data management mandates, such as directing how organisations should govern the secure storage of all types of sensitive information, whether on computer systems, physical media, or hard-copy documents.'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[\"output\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Let's ask a question that requires the custom Market Cap tool.**" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will use the market_cap tool to find the market capitalization of Apple and Microsoft. Then, I will use Python to calculate the difference between the two.\n", + "{'tool_name': 'market_cap', 'parameters': {'ticker': 'AAPL'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'id': 0, 'text': 'Market cap for AAPL: $2927279690000'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'market_cap', 'parameters': {'ticker': 'MSFT'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'id': 0, 'text': 'Market cap for MSFT: $3023872485050'}]\u001b[0m" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Python REPL can execute arbitrary code. Use with caution.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32;1m\u001b[1;3m\n", + "The market capitalization of Apple is $2,927,279,690,000 and the market capitalization of Microsoft is $3,023,872,485,050. I will now use Python to calculate the difference between the two.\n", + "{'tool_name': 'python_interpreter', 'parameters': {'code': 'apple_market_cap = 2927279690000\\nmicrosoft_market_cap = 3023872485050\\n\\ndifference = abs(microsoft_market_cap - apple_market_cap)\\n\\nprint(f\"The difference in market capitalization between Apple and Microsoft is {difference} dollars.\")'}}\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mThe difference in market capitalization between Apple and Microsoft is 96592795050 dollars.\n", + "\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2\n", + "Cited Documents: 0,1,2\n", + "Answer: The market capitalization of Apple is $2,927,279,690,000 and the market capitalization of Microsoft is $3,023,872,485,050. The difference in market capitalization between the two companies is $96,592,795,050.\n", + "Grounded answer: The market capitalization of Apple is $2,927,279,690,000 and the market capitalization of Microsoft is $3,023,872,485,050. The difference in market capitalization between the two companies is $96,592,795,050.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + } + ], + "source": [ + "result = agent_executor.invoke(\n", + " {\n", + " \"input\": \"What is Apple capitalization compared to Microsoft? Calculate the difference\",\n", + " \"preamble\": preamble,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'The market capitalization of Apple is $2,927,279,690,000 and the market capitalization of Microsoft is $3,023,872,485,050. The difference in market capitalization between the two companies is $96,592,795,050.'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[\"output\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Let's ask a question that does not require any tools.**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will respond to the user's greeting.\n", + "{'tool_name': 'directly_answer', 'parameters': {}}\n", + "\u001b[0mdirectly_answer is not a valid tool, try one of [vectorstore_search, internet_search, python_interpreter, market_cap].\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", + "Cited Documents: None\n", + "Answer: Hi! How can I help?\n", + "Grounded answer: Hi! How can I help?\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + } + ], + "source": [ + "result = agent_executor.invoke(\n", + " {\n", + " \"input\": \"Hi there!\",\n", + " \"preamble\": preamble,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Hi! How can I help?'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[\"output\"]" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/agents/Multi_Step_Tool_Use.ipynb b/notebooks/agents/Multi_Step_Tool_Use.ipynb deleted file mode 100644 index 01454c4c..00000000 --- a/notebooks/agents/Multi_Step_Tool_Use.ipynb +++ /dev/null @@ -1,515 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "EUYMLmXAF3W1" - }, - "source": [ - "# A ReAct agent with Command R+, achieving the same goals as Adaptive RAG | Add the custom tools\n", - "\n", - "Adaptive RAG is a strategy for RAG that unites (1) [query analysis](https://blog.langchain.dev/query-construction/) with (2) [active / self-corrective RAG](https://blog.langchain.dev/agentic-rag-with-langgraph/).\n", - "\n", - "In the paper, they report query analysis to route across:\n", - "- No Retrieval (LLM answers)\n", - "- Single-shot RAG\n", - "- Iterative RAG\n", - "\n", - "\n", - "We'll use Command R+, a recent release from Cohere that:\n", - "- Has strong accuracy on RAG, Tool Use and Agents\n", - "- Has 128k context\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W8yvOB2MQp07" - }, - "source": [ - "# Environment" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ujQVUvA9QlD4", - "outputId": "230c6a56-3ee3-4e0d-95af-2a261b8541d6" - }, - "outputs": [], - "source": [ - "%pip install --quiet langchain langchain_cohere tiktoken faiss-cpu beautifulsoup4 langchain_experimental matplotlib tabulate python-dotenv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Save your credentials in a .env file in your user root directory, so that you can retrieve securely" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from dotenv import load_dotenv\n", - "load_dotenv()\n", - "\n", - "COHERE_API_KEY = os.environ.get(\"COHERE_API_KEY\")\n", - "TAVILY_API_KEY = os.environ.get(\"TAVILY_API_KEY\") # Get your Free API key at https://app.tavily.com once you sign up\n", - "FMP_API_KEY = os.environ.get(\"FMP_API_KEY\") # Get your Free API key https://site.financialmodelingprep.com/ once you sign up" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "k3mrKxSsTfXO" - }, - "source": [ - "# Create tools\n", - "The ReAct agent will be equipped with these tools. The model can pick between\n", - "- web search\n", - "- RAG: retrieval from a vector store\n", - "- custom tool (call an external API)\n", - "- directly answering\n", - "\n", - "The model can use any of these tools, in any sequence of steps, and self-reflect." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "4kGUB4IRF3W5" - }, - "source": [ - "### Web search tool" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "hYsJgVY0F3W5" - }, - "outputs": [], - "source": [ - "from langchain_community.tools.tavily_search import TavilySearchResults\n", - "from langchain_core.pydantic_v1 import BaseModel, Field\n", - "\n", - "internet_search = TavilySearchResults()\n", - "internet_search.name = \"internet_search\"\n", - "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", - "\n", - "\n", - "class TavilySearchInput(BaseModel):\n", - " query: str = Field(description=\"Query to search the internet with\")\n", - "\n", - "\n", - "internet_search.args_schema = TavilySearchInput" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python interpreter tool" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.agents import Tool\n", - "from langchain_experimental.utilities import PythonREPL\n", - "\n", - "python_repl = PythonREPL()\n", - "repl_tool = Tool(\n", - " name=\"python_repl\",\n", - " description=\"Executes python code and returns the result. The code runs in a static sandbox without interactive mode, so print output or save output to a file.\",\n", - " func=python_repl.run,\n", - ")\n", - "repl_tool.name = \"python_interpreter\"\n", - "\n", - "# from langchain_core.pydantic_v1 import BaseModel, Field\n", - "class ToolInput(BaseModel):\n", - " code: str = Field(description=\"Python code to execute.\")\n", - "repl_tool.args_schema = ToolInput" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "NxDa_Em0tuas" - }, - "source": [ - "### RAG tool" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "0QyahrNPtwEi" - }, - "outputs": [], - "source": [ - "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", - "from langchain_cohere import CohereEmbeddings\n", - "from langchain_community.document_loaders import WebBaseLoader\n", - "from langchain_community.vectorstores import FAISS\n", - "\n", - "# Set embeddings\n", - "embd = CohereEmbeddings()\n", - "\n", - "# Docs to index\n", - "urls = [\n", - " \"https://www.mayerbrown.com/en/insights/publications/2023/03/new-data-standards-pending-for-federally-regulated-financial-entities\",\n", - " \"https://plaid.com/resources/open-finance/what-is-fdx/\",\n", - " \"https://www.egnyte.com/guides/financial-services/financial-data-compliance\",\n", - "]\n", - "\n", - "# Load\n", - "docs = [WebBaseLoader(url).load() for url in urls]\n", - "docs_list = [item for sublist in docs for item in sublist]\n", - "\n", - "# Split\n", - "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", - " chunk_size=512, chunk_overlap=0\n", - ")\n", - "doc_splits = text_splitter.split_documents(docs_list)\n", - "\n", - "# Add to vectorstore\n", - "vectorstore = FAISS.from_documents(\n", - " documents=doc_splits,\n", - " embedding=embd,\n", - ")\n", - "\n", - "vectorstore_retriever = vectorstore.as_retriever()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "eoa3toXfdGkI" - }, - "outputs": [], - "source": [ - "from langchain.tools.retriever import create_retriever_tool\n", - "\n", - "vectorstore_search = create_retriever_tool(\n", - " retriever=vectorstore_retriever,\n", - " name=\"vectorstore_search\",\n", - " description=\"Retrieve relevant info from a vectorstore that contains documents related to Data Compliance for Financial Services and its regulation.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Custom Tool For Market Capitalization\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. Define the function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import requests\n", - "\n", - "# Function to get the market capitalization of a ticker symbol\n", - "def get_market_cap(ticker):\n", - " url = f\"https://financialmodelingprep.com/api/v3/market-capitalization/{ticker}?apikey={FMP_API_KEY}\"\n", - " response = requests.get(url)\n", - " if response.status_code == 200:\n", - " data = response.json()\n", - " if data and isinstance(data, list) and len(data) > 0:\n", - " market_cap = data[0].get('marketCap', 'No market cap data available')\n", - " return [{'id': 0, 'text': f'Market cap for {ticker}: ${market_cap}'}]\n", - " else:\n", - " return \"No data available for the specified ticker.\"\n", - " else:\n", - " return \"Failed to retrieve data from the API.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Define the Custom Tool" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.tools import tool\n", - "\n", - "@tool\n", - "def market_cap(ticker: str) -> list:\n", - " \"\"\"This tool is only used to find market capitalization. Do not use it for anything else. Find the ticker when asked about capitalization. The ticker symbol of the company (e.g., AAPL which is the ticker for Apple Inc, MSFT for Microsoft )\"\"\"\n", - " return get_market_cap(ticker)\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "2ENQAfYXRG9Q" - }, - "source": [ - "# Create the ReAct Agent\n", - "The model can smartly pick the right tool(s) for the user query, call them in any sequence of steps, analyze the results and self-reflect." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "hx-Ew1i5F3W4" - }, - "outputs": [], - "source": [ - "from langchain.agents import AgentExecutor\n", - "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", - "from langchain_core.prompts import ChatPromptTemplate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "BPo3ZIHkF3W4" - }, - "outputs": [], - "source": [ - "# LLM\n", - "from langchain_cohere.chat_models import ChatCohere\n", - "\n", - "chat = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", - "\n", - "# Preamble\n", - "preamble = \"\"\"\n", - "Use all tools that are available to answear the question. \n", - "If the query covers the topics of Federal Financial Institutions, use the vectorstore search first.\n", - "If the query covers market capitalization, use the market cap tool first.\n", - "You are equipped with an internet search tool, and python interpreter, a market cap api, and a special vectorstore of information about Data Compliance for Financial Services.\n", - "\n", - "\"\"\"\n", - "\n", - "# Prompt\n", - "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "\n", - "# Create the ReAct agent\n", - "agent = create_cohere_react_agent(\n", - " llm=chat,\n", - " tools=[vectorstore_search, internet_search, repl_tool, market_cap],\n", - " prompt=prompt,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "dks-7TGGtdLE" - }, - "outputs": [], - "source": [ - "agent_executor = AgentExecutor(\n", - " agent=agent, tools=[vectorstore_search, internet_search, repl_tool, market_cap], verbose=True\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "v7L1aBHds1pj" - }, - "source": [ - "# Testing the ReAct agent" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ibo31dsHEjPv" - }, - "source": [ - "**Let's ask a question that requires web search.**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "AW_8C7mszsVE", - "outputId": "9be7067f-a776-4688-8864-db873d1fb65a" - }, - "outputs": [], - "source": [ - "result = agent_executor.invoke(\n", - " {\n", - " \"input\": \"How does the current interest rate environment affect the bond market?\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"output\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "lKkxSvJmEn8Z" - }, - "source": [ - "**Let's ask a question that requires RAG retrieval from the vector db.**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "Jl0JNX2TF3W5", - "outputId": "2ccb747c-e702-4473-f587-47271e0c71b2" - }, - "outputs": [], - "source": [ - "result = agent_executor.invoke(\n", - " {\n", - " \"input\": \"What are the primary functions of the Federal Financial Institutions Examination Council (FFIEC)?\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"output\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Let's ask a question that requires Market Cap.**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result = agent_executor.invoke(\n", - " {\n", - " \"input\": \"What is Apple capitalization compared to Microsoft? Calculate the difference\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"output\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Let's ask a question that requires Internet Search.**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result = agent_executor.invoke(\n", - " {\n", - " \"input\": \"Hi there!\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"output\"]" - ] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "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.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/notebooks/agents/Vanilla_Multi_Step_Tool_Use.ipynb b/notebooks/agents/Vanilla_Multi_Step_Tool_Use.ipynb index 550e7d87..bfded608 100644 --- a/notebooks/agents/Vanilla_Multi_Step_Tool_Use.ipynb +++ b/notebooks/agents/Vanilla_Multi_Step_Tool_Use.ipynb @@ -1,979 +1,917 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "aH1iAdZiURXh" + }, + "source": [ + "# Multi-Step Tool Use\n", + "\n", + "Tool use allows developers to connect Cohere's models to external tools like search engines, APIs, functions, databases, etc.\n", + "\n", + "Multi-step tool use is an extension of this basic idea, and allows the model to call more than one tool in a sequence of steps, using the results from one tool call in a subsequent step. This process allows the language model to reason, perform dynamic actions, and quickly adapt on the basis of information coming from external sources.\n", + "\n", + "The recommended way to achieve [multi-step tool use with Cohere](https://docs.cohere.com/docs/multi-step-tool-use) is by leveraging the [Langchain framework](https://python.langchain.com/docs/integrations/providers/cohere#react-agent) in Python." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PVT6Sl3msjNe" + }, + "source": [ + "## Install Dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { "colab": { - "provenance": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" + "base_uri": "https://localhost:8080/" + }, + "id": "0m31LaFDjCIY", + "outputId": "7177e241-a864-47ed-cf0a-5fc9fa70a7ec" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m812.8/812.8 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[32m194.1/194.1 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m9.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m276.8/276.8 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m87.5/87.5 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m145.9/145.9 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m21.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.8/144.8 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] } + ], + "source": [ + "! pip install --quiet langchain langchain_cohere langchain_experimental" + ] }, - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# Multi-Step Tool Use\n", - "\n", - "Tool use allows developers to connect Cohere's models to external tools like search engines, APIs, functions, databases, etc.\n", - "\n", - "Multi-step tool use is an extension of this basic idea, and allows the model to call more than one tool in a sequence of steps, using the results from one tool call in a subsequent step. This process allows the language model to reason, perform dynamic actions, and quickly adapt on the basis of information coming from external sources.\n", - "\n", - "The recommended way to achieve [multi-step tool use with Cohere](https://docs.cohere.com/docs/multi-step-tool-use) is by leveraging the [Langchain framework](https://python.langchain.com/docs/integrations/providers/cohere#react-agent) in Python." - ], - "metadata": { - "id": "aH1iAdZiURXh" - } - }, - { - "cell_type": "markdown", - "source": [ - "## Install Dependencies" - ], - "metadata": { - "id": "PVT6Sl3msjNe" - } - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "0m31LaFDjCIY", - "outputId": "7177e241-a864-47ed-cf0a-5fc9fa70a7ec" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m812.8/812.8 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[32m194.1/194.1 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m9.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m276.8/276.8 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m87.5/87.5 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m145.9/145.9 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m21.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.8/144.8 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ], - "source": [ - "! pip install --quiet langchain langchain_cohere langchain_experimental" - ] - }, - { - "cell_type": "code", - "source": [ - "# LLM\n", - "import os\n", - "os.environ['COHERE_API_KEY'] = " - ], - "metadata": { - "id": "K0GELKJVnadW" - }, - "execution_count": 2, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## Define tools\n", - "\n", - "Your agent will be equipped with the following tools. The model can pick between\n", - "\n", - "- doing a search on the web\n", - "- and/or retrieving data from a vector store\n", - "- and/or using a python interpreter\n", - "- and/or directly answering [ this tool comes out of the box! ]\n", - "\n", - "Plus the model can self-reflect." - ], - "metadata": { - "id": "6l1pDbAmsptW" - } - }, - { - "cell_type": "markdown", - "source": [ - "#### Web search\n", - "You can easily equip your agent with web search!" - ], - "metadata": { - "id": "_9riBTvIVnaN" - } - }, - { - "cell_type": "code", - "source": [ - "from langchain_community.tools.tavily_search import TavilySearchResults\n", - "\n", - "os.environ[\"TAVILY_API_KEY\"] = # you can create an API key for free on Tavily's website\n", - "\n", - "internet_search = TavilySearchResults()\n", - "internet_search.name = \"internet_search\"\n", - "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", - "\n", - "\n", - "from langchain_core.pydantic_v1 import BaseModel, Field\n", - "class TavilySearchInput(BaseModel):\n", - " query: str = Field(description=\"Query to search the internet with\")\n", - "internet_search.args_schema = TavilySearchInput" - ], - "metadata": { - "id": "6wMNTOGNVvwA" - }, - "execution_count": 3, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "#### Vector store\n", - "You can easily equip your agent with a vector store!" - ], - "metadata": { - "id": "pax1SemzX6Kg" - } - }, - { - "cell_type": "code", - "source": [ - "!pip --quiet install faiss-cpu tiktoken" - ], - "metadata": { - "id": "cc4d4pRFndYu", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "6478fd6b-5618-4d0b-8928-44f78e3ca7e6" - }, - "execution_count": 4, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m27.0/27.0 MB\u001b[0m \u001b[31m41.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m58.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", - "from langchain_community.document_loaders import WebBaseLoader\n", - "from langchain_community.vectorstores import FAISS\n", - "from langchain_cohere import CohereEmbeddings\n", - "\n", - "# Set embeddings\n", - "embd = CohereEmbeddings()\n", - "\n", - "# Docs to index\n", - "urls = [\n", - " \"https://paulgraham.com/best.html\",\n", - "]\n", - "\n", - "# Load\n", - "docs = [WebBaseLoader(url).load() for url in urls]\n", - "docs_list = [item for sublist in docs for item in sublist]\n", - "\n", - "# Split\n", - "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", - " chunk_size=512, chunk_overlap=0\n", - ")\n", - "doc_splits = text_splitter.split_documents(docs_list)\n", - "\n", - "# Add to vectorstore\n", - "vectorstore = FAISS.from_documents(\n", - " documents=doc_splits,\n", - " embedding=embd,\n", - ")\n", - "\n", - "vectorstore_retriever = vectorstore.as_retriever()\n" - ], - "metadata": { - "id": "eqcorKP4YEH6" - }, - "execution_count": 5, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "from langchain.tools.retriever import create_retriever_tool\n", - "\n", - "vectorstore_search = create_retriever_tool(\n", - " retriever=vectorstore_retriever,\n", - " name=\"vectorstore_search\",\n", - " description=\"Retrieve relevant info from a vectorstore that contains information from Paul Graham about how to write good essays.\"\n", - ")" - ], - "metadata": { - "id": "eQFNJ-38abRd" - }, - "execution_count": 6, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "#### Python interpreter tool\n", - "You can easily equip your agent with a python interpreter!" - ], - "metadata": { - "id": "aB90i9W5YqWi" - } - }, - { - "cell_type": "code", - "source": [ - "from langchain.agents import Tool\n", - "from langchain_experimental.utilities import PythonREPL\n", - "\n", - "python_repl = PythonREPL()\n", - "python_tool = Tool(\n", - " name=\"python_repl\",\n", - " description=\"Executes python code and returns the result. The code runs in a static sandbox without interactive mode, so print output or save output to a file.\",\n", - " func=python_repl.run,\n", - ")\n", - "python_tool.name = \"python_interpreter\"\n", - "\n", - "# from langchain_core.pydantic_v1 import BaseModel, Field\n", - "class ToolInput(BaseModel):\n", - " code: str = Field(description=\"Python code to execute.\")\n", - "python_tool.args_schema = ToolInput" - ], - "metadata": { - "id": "AN-4FqXKYEFw" - }, - "execution_count": 7, - "outputs": [] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "8vj868w_YED_" - }, - "execution_count": 7, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "#### Transform any Python function in a Tool\n", - "You can easily equip your agent with any Python function!" - ], - "metadata": { - "id": "2SDCaoypexGL" - } - }, - { - "cell_type": "code", - "source": [ - "from langchain_core.tools import tool\n", - "import random\n", - "\n", - "@tool\n", - "def random_operation_tool(a: int, b: int):\n", - " \"\"\"Calculates a random operation between the inputs.\"\"\"\n", - " coin_toss = random.uniform(0, 1)\n", - " if coin_toss > 0.5:\n", - " return {'output': a*b}\n", - " else:\n", - " return {'output': a+b}\n", - "\n", - "random_operation_tool.name = \"random_operation\" # use python case\n", - "random_operation_tool.description = \"Calculates a random operation between the inputs.\"\n", - "\n", - "from langchain_core.pydantic_v1 import BaseModel, Field\n", - "class random_operation_inputs(BaseModel):\n", - " a: int = Field(description=\"First input\")\n", - " b: int = Field(description=\"Second input\")\n", - "random_operation_tool.args_schema = random_operation_inputs" - ], - "metadata": { - "id": "DYUJT2xKewny" - }, - "execution_count": 8, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## Create ReAct Agent\n", - "\n", - "The model can smartly pick the right tool(s) for the user query, call them in any sequence, analyze the results and self-reflect. \n", - "Once the model considers it has enough information to answer the user question, it generates the final answer." - ], - "metadata": { - "id": "hcspRBsRY2ED" - } - }, - { - "cell_type": "code", - "source": [ - "from langchain.agents import AgentExecutor\n", - "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", - "from langchain_core.prompts import ChatPromptTemplate\n", - "from langchain_cohere.chat_models import ChatCohere\n", - "\n", - "# LLM\n", - "llm = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", - "\n", - "# Preamble\n", - "preamble = \"\"\"\n", - "You are an expert who answers the user's question with the most relevant datasource. You are equipped with an internet search tool and a special vectorstore of information about how to write good essays.\n", - "You also have a 'random_operation_tool' tool, you must use it to compute the random operation between two numbers.\n", - "\"\"\"\n", - "\n", - "\n", - "# Prompt template\n", - "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "\n", - "# Create the ReAct agent\n", - "agent = create_cohere_react_agent(\n", - " llm=llm,\n", - " tools=[internet_search, vectorstore_search, python_tool, random_operation_tool],\n", - " prompt=prompt,\n", - ")\n", - "\n", - "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool, random_operation_tool], verbose=True)" - ], - "metadata": { - "id": "CY83aAprYECO" - }, - "execution_count": 13, - "outputs": [] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "RK0NaqngYD_J" - }, - "execution_count": 13, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## Ask a standalone question to the ReAct agent\n", - "A question that requires using a predefined tool from Langchain" - ], - "metadata": { - "id": "mzTQcVXSaBe7" - } - }, - { - "cell_type": "code", - "source": [ - "response = agent_executor.invoke({\n", - " \"input\": \"I want to write an essay about the Roman Empire. Any tips for writing an essay? Any fun facts?\",\n", - " \"preamble\": preamble,\n", - "})\n", - "\n", - "response['output']\n", - "\n", - "# note that the model smartly looks in the vector db, and then online" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "rR2hWVp-aEsU", - "outputId": "fcf9b8b3-7027-4679-c06d-ef166f016892" + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "K0GELKJVnadW" + }, + "outputs": [], + "source": [ + "# LLM\n", + "import os\n", + "os.environ['COHERE_API_KEY'] = " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6l1pDbAmsptW" + }, + "source": [ + "## Define tools\n", + "\n", + "Your agent will be equipped with the following tools. The model can pick between\n", + "\n", + "- doing a search on the web\n", + "- and/or retrieving data from a vector store\n", + "- and/or using a python interpreter\n", + "- and/or directly answering [ this tool comes out of the box! ]\n", + "\n", + "Plus the model can self-reflect." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_9riBTvIVnaN" + }, + "source": [ + "#### Web search\n", + "You can easily equip your agent with web search!" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "6wMNTOGNVvwA" + }, + "outputs": [], + "source": [ + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "\n", + "os.environ[\"TAVILY_API_KEY\"] = # you can create an API key for free on Tavily's website\n", + "\n", + "internet_search = TavilySearchResults()\n", + "internet_search.name = \"internet_search\"\n", + "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", + "\n", + "\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class TavilySearchInput(BaseModel):\n", + " query: str = Field(description=\"Query to search the internet with\")\n", + "internet_search.args_schema = TavilySearchInput" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pax1SemzX6Kg" + }, + "source": [ + "#### Vector store\n", + "You can easily equip your agent with a vector store!" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "cc4d4pRFndYu", + "outputId": "6478fd6b-5618-4d0b-8928-44f78e3ca7e6" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m27.0/27.0 MB\u001b[0m \u001b[31m41.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m58.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "!pip --quiet install faiss-cpu tiktoken" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "eqcorKP4YEH6" + }, + "outputs": [], + "source": [ + "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import FAISS\n", + "from langchain_cohere import CohereEmbeddings\n", + "\n", + "# Set embeddings\n", + "embd = CohereEmbeddings()\n", + "\n", + "# Docs to index\n", + "urls = [\n", + " \"https://paulgraham.com/best.html\",\n", + "]\n", + "\n", + "# Load\n", + "docs = [WebBaseLoader(url).load() for url in urls]\n", + "docs_list = [item for sublist in docs for item in sublist]\n", + "\n", + "# Split\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=512, chunk_overlap=0\n", + ")\n", + "doc_splits = text_splitter.split_documents(docs_list)\n", + "\n", + "# Add to vectorstore\n", + "vectorstore = FAISS.from_documents(\n", + " documents=doc_splits,\n", + " embedding=embd,\n", + ")\n", + "\n", + "vectorstore_retriever = vectorstore.as_retriever()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "eQFNJ-38abRd" + }, + "outputs": [], + "source": [ + "from langchain.tools.retriever import create_retriever_tool\n", + "\n", + "vectorstore_search = create_retriever_tool(\n", + " retriever=vectorstore_retriever,\n", + " name=\"vectorstore_search\",\n", + " description=\"Retrieve relevant info from a vectorstore that contains information from Paul Graham about how to write good essays.\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aB90i9W5YqWi" + }, + "source": [ + "#### Python interpreter tool\n", + "You can easily equip your agent with a python interpreter!" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "AN-4FqXKYEFw" + }, + "outputs": [], + "source": [ + "from langchain.agents import Tool\n", + "from langchain_experimental.utilities import PythonREPL\n", + "\n", + "python_repl = PythonREPL()\n", + "python_tool = Tool(\n", + " name=\"python_repl\",\n", + " description=\"Executes python code and returns the result. The code runs in a static sandbox without interactive mode, so print output or save output to a file.\",\n", + " func=python_repl.run,\n", + ")\n", + "python_tool.name = \"python_interpreter\"\n", + "\n", + "# from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class ToolInput(BaseModel):\n", + " code: str = Field(description=\"Python code to execute.\")\n", + "python_tool.args_schema = ToolInput" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2SDCaoypexGL" + }, + "source": [ + "#### Transform any Python function in a Tool\n", + "You can easily equip your agent with any Python function!" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "DYUJT2xKewny" + }, + "outputs": [], + "source": [ + "from langchain_core.tools import tool\n", + "import random\n", + "\n", + "@tool\n", + "def random_operation_tool(a: int, b: int):\n", + " \"\"\"Calculates a random operation between the inputs.\"\"\"\n", + " coin_toss = random.uniform(0, 1)\n", + " if coin_toss > 0.5:\n", + " return {'output': a*b}\n", + " else:\n", + " return {'output': a+b}\n", + "\n", + "random_operation_tool.name = \"random_operation\" # use python case\n", + "random_operation_tool.description = \"Calculates a random operation between the inputs.\"\n", + "\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "class random_operation_inputs(BaseModel):\n", + " a: int = Field(description=\"First input\")\n", + " b: int = Field(description=\"Second input\")\n", + "random_operation_tool.args_schema = random_operation_inputs" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hcspRBsRY2ED" + }, + "source": [ + "## Create ReAct Agent\n", + "\n", + "The model can smartly pick the right tool(s) for the user query, call them in any sequence, analyze the results and self-reflect. \n", + "Once the model considers it has enough information to answer the user question, it generates the final answer." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "id": "CY83aAprYECO" + }, + "outputs": [], + "source": [ + "from langchain.agents import AgentExecutor\n", + "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_cohere.chat_models import ChatCohere\n", + "\n", + "# LLM\n", + "llm = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", + "\n", + "# Preamble\n", + "preamble = \"\"\"\n", + "You are an expert who answers the user's question with the most relevant datasource. You are equipped with an internet search tool and a special vectorstore of information about how to write good essays.\n", + "You also have a 'random_operation_tool' tool, you must use it to compute the random operation between two numbers.\n", + "\"\"\"\n", + "\n", + "\n", + "# Prompt template\n", + "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", + "\n", + "# Create the ReAct agent\n", + "agent = create_cohere_react_agent(\n", + " llm=llm,\n", + " tools=[internet_search, vectorstore_search, python_tool, random_operation_tool],\n", + " prompt=prompt,\n", + ")\n", + "\n", + "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool, random_operation_tool], verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mzTQcVXSaBe7" + }, + "source": [ + "## Ask a standalone question to the ReAct agent\n", + "A question that requires using a predefined tool from Langchain" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "rR2hWVp-aEsU", + "outputId": "fcf9b8b3-7027-4679-c06d-ef166f016892" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for tips on writing an essay and fun facts about the Roman Empire.\n", + "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'tips for writing an essay'}}\n", + "\u001b[0m\u001b[33;1m\u001b[1;3mbe? I should have asked how do you write essays well? Though\n", + "these seem only phrasing apart, their answers diverge. The answer\n", + "to the first question, as we've seen, isn't really about essay\n", + "writing. The second question forces it to be.Writing essays, at its best, is a way of discovering ideas. How do\n", + "you do that well? How do you discover by writing?An essay should ordinarily start with what I'm going to call a\n", + "question, though I mean this in a very general sense: it doesn't\n", + "have to be a question grammatically, just something that acts like\n", + "one in the sense that it spurs some response.How do you get this initial question? It probably won't work to\n", + "choose some important-sounding topic at random and go at it.\n", + "Professional traders won't even trade unless they have what they\n", + "call an edge — a convincing story about why in some class of\n", + "trades they'll win more than they lose. Similarly, you shouldn't\n", + "attack a topic unless you have a way in — some new insight about\n", + "it or way of approaching it.You don't need to have a complete thesis; you just need some kind\n", + "of gap you can explore. In fact, merely having questions about\n", + "something other people take for granted can be edge enough.If you come across a question that's sufficiently puzzling, it could\n", + "be worth exploring even if it doesn't seem very momentous. Many an\n", + "important discovery has been made by pulling on a thread that seemed\n", + "insignificant at first. How can they all be finches? \n", + "[2]Once you've got a question, then what? You start thinking out loud\n", + "about it. Not literally out loud, but you commit to a specific\n", + "string of words in response, as you would if you were talking. This\n", + "initial response is usually mistaken or incomplete. Writing converts\n", + "your ideas from vague to bad. But that's a step forward, because\n", + "once you can see the brokenness, you can fix it.Perhaps beginning writers are alarmed at the thought of starting\n", + "with something mistaken or incomplete, but you shouldn't be, because\n", + "this is why essay writing works. Forcing yourself to commit to some\n", + "specific string of words gives you a starting point, and if it's\n", + "wrong, you'll see that when you reread it. At least half of essay\n", + "writing is rereading what you've written and asking is this correct\n", + "\n", + "didn't have edge with any of them. To start writing an essay, you\n", + "need a topic plus some initial insight about it, and you can't\n", + "generate those systematically. If only. \n", + "[9]You can probably cause yourself to have more of them, though. The\n", + "quality of the ideas that come out of your head depends on what goes\n", + "in, and you can improve that in two dimensions, breadth and depth.You can't learn everything, so getting breadth implies learning\n", + "about topics that are very different from one another. When I tell\n", + "people about my book-buying trips to Hay and they ask what I buy\n", + "books about, I usually feel a bit sheepish answering, because the\n", + "topics seem like a laundry list of unrelated subjects. But perhaps\n", + "that's actually optimal in this business.You can also get ideas by talking to people, by doing and building\n", + "things, and by going places and seeing things. I don't think it's\n", + "important to talk to new people so much as the sort of people who\n", + "make you have new ideas. I get more new ideas after talking for an\n", + "afternoon with Robert Morris than from talking to 20 new smart\n", + "people. I know because that's what a block of office hours at Y\n", + "Combinator consists of.While breadth comes from reading and talking and seeing, depth comes\n", + "from doing. The way to really learn about some domain is to have\n", + "to solve problems in it. Though this could take the form of writing,\n", + "I suspect that to be a good essayist you also have to do, or have\n", + "done, some other kind of work. That may not be true for most other\n", + "fields, but essay writing is different. You could spend half your\n", + "time working on something else and be net ahead, so long as it was\n", + "hard.I'm not proposing that as a recipe so much as an encouragement to\n", + "those already doing it. If you've spent all your life so far working\n", + "on other things, you're already halfway there. Though of course to\n", + "be good at writing you have to like it, and if you like writing\n", + "you'd probably have spent at least some time doing it.Everything I've said about initial questions applies also to the\n", + "questions you encounter in writing the essay. They're the same\n", + "thing; every subtree of an essay is usually a shorter essay, just\n", + "as every subtree of a Calder mobile is a smaller mobile. So any\n", + "\n", + "You don't have to get an answer right the first time, but there's\n", + "no excuse for not getting it right eventually, because you can keep\n", + "rewriting till you do. And this is not just a theoretical possibility.\n", + "It's a pretty accurate description of the way I work. I'm rewriting\n", + "as we speak.But although I wish I could say that writing great essays depends mostly\n", + "on effort, in the limit case it's inspiration that makes the\n", + "difference. In the limit case, the questions are the harder thing\n", + "to get. That pool has no bottom.How to get more questions? That is the most important question of\n", + "all.Notes[1]\n", + "There might be some resistance to this conclusion on the\n", + "grounds that some of these discoveries could only be understood by\n", + "a small number of readers. But you get into all sorts of difficulties\n", + "if you want to disqualify essays on this account. How do you decide\n", + "where the cutoff should be? If a virus kills off everyone except a \n", + "handful of people sequestered at Los Alamos,\n", + "could an essay that had been disqualified now be eligible? Etc.Darwin's 1844 essay was derived from an earlier version written in 1839.\n", + "Extracts from it were published in 1858.[2]\n", + "When you find yourself very curious about an apparently minor\n", + "question, that's an exciting sign. Evolution has designed you to\n", + "pay attention to things that matter. So when you're very curious\n", + "about something random, that could mean you've unconsciously noticed\n", + "it's less random than it seems.[3]\n", + "Corollary: If you're not intellectually honest, your writing\n", + "won't just be biased, but also boring, because you'll miss all the\n", + "ideas you'd have discovered if you pushed for the truth.[4]\n", + "Sometimes this process begins before you start writing.\n", + "Sometimes you've already figured out the first few things you want\n", + "to say. Schoolchildren are often taught they should decide everything\n", + "they want to say, and write this down as an outline before they\n", + "start writing the essay itself. Maybe that's a good way to get them\n", + "started — or not, I don't know — but it's antithetical to the\n", + "spirit of essay writing. The more detailed your outline, the less\n", + "your ideas can benefit from the sort of discovery that essays are for.[5]\n", + "The problem with this type of \"greedy\" algorithm is that you\n", + "\n", + "technique that gets you good initial questions also gets you good\n", + "whole essays.At some point the cycle of question and response reaches what feels\n", + "like a natural end. Which is a little suspicious; shouldn't every\n", + "answer suggest more questions? I think what happens is that you\n", + "start to feel sated. Once you've covered enough interesting ground,\n", + "you start to lose your appetite for new questions. Which is just\n", + "as well, because the reader is probably feeling sated too. And it's\n", + "not lazy to stop asking questions, because you could instead be\n", + "asking the initial question of a new essay.That's the ultimate source of drag on the connectedness of ideas:\n", + "the discoveries you make along the way. If you discover enough\n", + "starting from question A, you'll never make it to question B. Though\n", + "if you keep writing essays you'll gradually fix this problem by\n", + "burning off such discoveries. So bizarrely enough, writing lots of\n", + "essays makes it as if the space of ideas were more highly connected.When a subtree comes to an end, you can do one of two things. You\n", + "can either stop, or pull the Cubist trick of laying separate subtrees\n", + "end to end by returning to a question you skipped earlier. Usually\n", + "it requires some sleight of hand to make the essay flow continuously\n", + "at this point, but not this time. This time I actually need an\n", + "example of the phenomenon. For example, we discovered earlier that\n", + "the best possible essay wouldn't usually be timeless in the way the\n", + "best painting would. This seems surprising enough to be\n", + "worth investigating further.There are two senses in which an essay can be timeless: to be about\n", + "a matter of permanent importance, and always to have the same effect\n", + "on readers. With art these two senses blend together. Art that\n", + "looked beautiful to the ancient Greeks still looks beautiful to us.\n", + "But with essays the two senses diverge, because essays\n", + "teach, and you can't teach people something they already know.\n", + "Natural selection is certainly a matter of permanent importance,\n", + "but an essay explaining it couldn't have the same effect on us that\n", + "it would have had on Darwin's contemporaries, precisely because his\n", + "ideas were so successful that everyone already knows about them.\n", + "[10]I imagined when I started writing this that the best possible essay\n", + "would be timeless in the stricter, evergreen sense: that it would\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the roman empire'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.natgeokids.com/uk/discover/history/romans/10-facts-about-the-ancient-romans/', 'content': 'i love this website\\nBIG BOBBY\\nbooby\\nI love shell my bae;)\\ni like bobby fishes ;0\\nI like turtles\\nOmg soy cool\\ngreeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatttttttttttttttttttttttt\\nbest fact ever\\nthis artical is cool\\nHANDY\\nrubbish did not help what so ever\\nha\\nRocking\\nTHIS IS THE BEST\\nproper rad in it cool\\nthis is cool\\nawesomeness\\nawsome\\nawsome\\nthank you captain\\nit is a lot of help\\ni like this\\nwebsite it helps me on my projects and isabel likes munier\\nmark uses this for research\\nlot of help\\nthis is awsome\\nTHE BEST BOOBOO\\nCool webpage helped me get 4 housepoints\\n This helped me A LOT on a school project\\ncool wow awesomoe\\nCOOL WEBSITE LOL\\nthis helped me with a school project :)\\nthat was awesome\\ncool\\nthat helped me out for my research test\\nReally its very cool really COOL\\nLIKE COOL best website so far its nice\\nI love it\\nnice facts\\nIt help with my history\\n i mean u made animaljam a awesome nice safe place for kids and this site to have kids a safe website to get facts for reports and stuff\\nLots of Love ,\\nRose\\npretty good website if u ask me\\nbut definently not gonna use it on a daily basis\\nIll try it again another time\\ngood\\nCool webcite\\nterrible\\nquite impressive\\nAwesome website it real helps\\nits good\\nthis is a great website! You really a lot with my project!:)\\nthis has helleped\\nme get\\nmy progect\\ndone\\nthank you\\nsoooooooooooooooooo\\nmuchchchchchch\\nthis helleped me\\nsooooooooo much with my progect thank you\\nvery good website\\nthank us very much your nice one today!!\\n'}, {'url': 'https://ohfact.com/roman-empire-facts/', 'content': 'Learn about the ancient Roman Civilization, its history, culture, army, architecture, food and more from this list of 27 facts. Discover how the Romans started, conquered, lived, died and influenced the world with their legends, myths and facts.'}, {'url': 'https://factnight.com/fun-facts-about-the-roman-empire/', 'content': 'The Roman Empire was one of the most influential and significant civilizations in world history. At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people. From its legendary beginnings and remarkable achievements to its eventual decline and fall, the Roman Empire is a fascinating topic full of little-known facts and intriguing trivia.'}, {'url': 'https://www.historyhit.com/facts-about-ancient-rome-and-the-romans/', 'content': 'The Enduring Legacy of C.S. Lewis\\nMargaret J. Winkler: A Forgotten Pioneer in Disney’s Success\\n10 Facts About Harper Lee\\nAntarctica Expedition Cruise\\nUncover Pompeii\\nSophie Hay and Tristan Hughes\\nRediscovering Richard III with Matt Lewis\\nOrder the History Hit Miscellany\\nHistory Hit Holidays\\nGift Subscriptions\\n100 Facts About Ancient Rome and the Romans\\nRome wasn’t built in a day, as the cliché reminds us. The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire\\nBarbarian factions, tribes and war leaders were now a factor in the power struggles at the top of Roman politics and one of the once-strong boundaries of the Empire had proved to be permeable.\\n Related Articles\\n10 Facts About Saint Andrew\\nThe Rise of Pompey the Great, the ‘Roman Alexander’\\nWatch and Listen\\nCleopatra\\nSex in Ancient Rome\\nRelated Locations\\nBaelo Claudia\\nMausoleum of Cecilia Metella\\nColin Ricketts\\n30 July 2021\\n By the fourth century BC, the story was accepted by Romans who were proud of their warrior founder\\nThe story was included in the first history of the city, by the Greek writer Diocles of Peparethus, and the twins and their wolf step-mother were depicted on Rome’s first coins.\\n The History Hit Miscellany of Facts, Figures and Fascinating Finds\\nA History of England: Part One\\nDragons: Myth & Reality\\nA Tudor Wonder - Hardwick Hall\\nThe Battle of Shrewsbury\\nEurope’s 1848 Revolutions\\nThe Boston Tea Party\\nHow Did 3 People Seemingly Escape From Alcatraz?\\n'}, {'url': 'https://www.countryfaq.com/facts-about-the-roman-empire/', 'content': 'Facts about the Roman Empire. Explore some of the interesting, fun, cool facts bout the Roman Empire: 1. The Magnificent Roman Empire. The Roman Empire, a colossal entity of unparalleled grandeur, occupies an indomitable position within the annals of human history, a name that resonates resoundingly across the eons.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,3,4,5\n", + "Cited Documents: 0,3,4,5\n", + "Answer: Here are some tips for writing an essay:\n", + "- Start with a question that spurs some response.\n", + "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", + "- You don't need a complete thesis, just a gap to explore.\n", + "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", + "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", + "- You can get breadth by reading and talking about a wide range of topics.\n", + "- You can get depth by doing and having to solve problems.\n", + "- You can also get ideas by talking to people who make you have new ideas.\n", + "\n", + "Here are some fun facts about the Roman Empire:\n", + "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", + "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", + "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\n", + "Grounded answer: Here are some tips for writing an essay:\n", + "- Start with a question that spurs some response.\n", + "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", + "- You don't need a complete thesis, just a gap to explore.\n", + "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", + "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", + "- You can get breadth by reading and talking about a wide range of topics.\n", + "- You can get depth by doing and having to solve problems.\n", + "- You can also get ideas by talking to people who make you have new ideas.\n", + "\n", + "Here are some fun facts about the Roman Empire:\n", + "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", + "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", + "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" }, - "execution_count": 14, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for tips on writing an essay and fun facts about the Roman Empire.\n", - "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'tips for writing an essay'}}\n", - "\u001b[0m\u001b[33;1m\u001b[1;3mbe? I should have asked how do you write essays well? Though\n", - "these seem only phrasing apart, their answers diverge. The answer\n", - "to the first question, as we've seen, isn't really about essay\n", - "writing. The second question forces it to be.Writing essays, at its best, is a way of discovering ideas. How do\n", - "you do that well? How do you discover by writing?An essay should ordinarily start with what I'm going to call a\n", - "question, though I mean this in a very general sense: it doesn't\n", - "have to be a question grammatically, just something that acts like\n", - "one in the sense that it spurs some response.How do you get this initial question? It probably won't work to\n", - "choose some important-sounding topic at random and go at it.\n", - "Professional traders won't even trade unless they have what they\n", - "call an edge — a convincing story about why in some class of\n", - "trades they'll win more than they lose. Similarly, you shouldn't\n", - "attack a topic unless you have a way in — some new insight about\n", - "it or way of approaching it.You don't need to have a complete thesis; you just need some kind\n", - "of gap you can explore. In fact, merely having questions about\n", - "something other people take for granted can be edge enough.If you come across a question that's sufficiently puzzling, it could\n", - "be worth exploring even if it doesn't seem very momentous. Many an\n", - "important discovery has been made by pulling on a thread that seemed\n", - "insignificant at first. How can they all be finches? \n", - "[2]Once you've got a question, then what? You start thinking out loud\n", - "about it. Not literally out loud, but you commit to a specific\n", - "string of words in response, as you would if you were talking. This\n", - "initial response is usually mistaken or incomplete. Writing converts\n", - "your ideas from vague to bad. But that's a step forward, because\n", - "once you can see the brokenness, you can fix it.Perhaps beginning writers are alarmed at the thought of starting\n", - "with something mistaken or incomplete, but you shouldn't be, because\n", - "this is why essay writing works. Forcing yourself to commit to some\n", - "specific string of words gives you a starting point, and if it's\n", - "wrong, you'll see that when you reread it. At least half of essay\n", - "writing is rereading what you've written and asking is this correct\n", - "\n", - "didn't have edge with any of them. To start writing an essay, you\n", - "need a topic plus some initial insight about it, and you can't\n", - "generate those systematically. If only. \n", - "[9]You can probably cause yourself to have more of them, though. The\n", - "quality of the ideas that come out of your head depends on what goes\n", - "in, and you can improve that in two dimensions, breadth and depth.You can't learn everything, so getting breadth implies learning\n", - "about topics that are very different from one another. When I tell\n", - "people about my book-buying trips to Hay and they ask what I buy\n", - "books about, I usually feel a bit sheepish answering, because the\n", - "topics seem like a laundry list of unrelated subjects. But perhaps\n", - "that's actually optimal in this business.You can also get ideas by talking to people, by doing and building\n", - "things, and by going places and seeing things. I don't think it's\n", - "important to talk to new people so much as the sort of people who\n", - "make you have new ideas. I get more new ideas after talking for an\n", - "afternoon with Robert Morris than from talking to 20 new smart\n", - "people. I know because that's what a block of office hours at Y\n", - "Combinator consists of.While breadth comes from reading and talking and seeing, depth comes\n", - "from doing. The way to really learn about some domain is to have\n", - "to solve problems in it. Though this could take the form of writing,\n", - "I suspect that to be a good essayist you also have to do, or have\n", - "done, some other kind of work. That may not be true for most other\n", - "fields, but essay writing is different. You could spend half your\n", - "time working on something else and be net ahead, so long as it was\n", - "hard.I'm not proposing that as a recipe so much as an encouragement to\n", - "those already doing it. If you've spent all your life so far working\n", - "on other things, you're already halfway there. Though of course to\n", - "be good at writing you have to like it, and if you like writing\n", - "you'd probably have spent at least some time doing it.Everything I've said about initial questions applies also to the\n", - "questions you encounter in writing the essay. They're the same\n", - "thing; every subtree of an essay is usually a shorter essay, just\n", - "as every subtree of a Calder mobile is a smaller mobile. So any\n", - "\n", - "You don't have to get an answer right the first time, but there's\n", - "no excuse for not getting it right eventually, because you can keep\n", - "rewriting till you do. And this is not just a theoretical possibility.\n", - "It's a pretty accurate description of the way I work. I'm rewriting\n", - "as we speak.But although I wish I could say that writing great essays depends mostly\n", - "on effort, in the limit case it's inspiration that makes the\n", - "difference. In the limit case, the questions are the harder thing\n", - "to get. That pool has no bottom.How to get more questions? That is the most important question of\n", - "all.Notes[1]\n", - "There might be some resistance to this conclusion on the\n", - "grounds that some of these discoveries could only be understood by\n", - "a small number of readers. But you get into all sorts of difficulties\n", - "if you want to disqualify essays on this account. How do you decide\n", - "where the cutoff should be? If a virus kills off everyone except a \n", - "handful of people sequestered at Los Alamos,\n", - "could an essay that had been disqualified now be eligible? Etc.Darwin's 1844 essay was derived from an earlier version written in 1839.\n", - "Extracts from it were published in 1858.[2]\n", - "When you find yourself very curious about an apparently minor\n", - "question, that's an exciting sign. Evolution has designed you to\n", - "pay attention to things that matter. So when you're very curious\n", - "about something random, that could mean you've unconsciously noticed\n", - "it's less random than it seems.[3]\n", - "Corollary: If you're not intellectually honest, your writing\n", - "won't just be biased, but also boring, because you'll miss all the\n", - "ideas you'd have discovered if you pushed for the truth.[4]\n", - "Sometimes this process begins before you start writing.\n", - "Sometimes you've already figured out the first few things you want\n", - "to say. Schoolchildren are often taught they should decide everything\n", - "they want to say, and write this down as an outline before they\n", - "start writing the essay itself. Maybe that's a good way to get them\n", - "started — or not, I don't know — but it's antithetical to the\n", - "spirit of essay writing. The more detailed your outline, the less\n", - "your ideas can benefit from the sort of discovery that essays are for.[5]\n", - "The problem with this type of \"greedy\" algorithm is that you\n", - "\n", - "technique that gets you good initial questions also gets you good\n", - "whole essays.At some point the cycle of question and response reaches what feels\n", - "like a natural end. Which is a little suspicious; shouldn't every\n", - "answer suggest more questions? I think what happens is that you\n", - "start to feel sated. Once you've covered enough interesting ground,\n", - "you start to lose your appetite for new questions. Which is just\n", - "as well, because the reader is probably feeling sated too. And it's\n", - "not lazy to stop asking questions, because you could instead be\n", - "asking the initial question of a new essay.That's the ultimate source of drag on the connectedness of ideas:\n", - "the discoveries you make along the way. If you discover enough\n", - "starting from question A, you'll never make it to question B. Though\n", - "if you keep writing essays you'll gradually fix this problem by\n", - "burning off such discoveries. So bizarrely enough, writing lots of\n", - "essays makes it as if the space of ideas were more highly connected.When a subtree comes to an end, you can do one of two things. You\n", - "can either stop, or pull the Cubist trick of laying separate subtrees\n", - "end to end by returning to a question you skipped earlier. Usually\n", - "it requires some sleight of hand to make the essay flow continuously\n", - "at this point, but not this time. This time I actually need an\n", - "example of the phenomenon. For example, we discovered earlier that\n", - "the best possible essay wouldn't usually be timeless in the way the\n", - "best painting would. This seems surprising enough to be\n", - "worth investigating further.There are two senses in which an essay can be timeless: to be about\n", - "a matter of permanent importance, and always to have the same effect\n", - "on readers. With art these two senses blend together. Art that\n", - "looked beautiful to the ancient Greeks still looks beautiful to us.\n", - "But with essays the two senses diverge, because essays\n", - "teach, and you can't teach people something they already know.\n", - "Natural selection is certainly a matter of permanent importance,\n", - "but an essay explaining it couldn't have the same effect on us that\n", - "it would have had on Darwin's contemporaries, precisely because his\n", - "ideas were so successful that everyone already knows about them.\n", - "[10]I imagined when I started writing this that the best possible essay\n", - "would be timeless in the stricter, evergreen sense: that it would\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the roman empire'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.natgeokids.com/uk/discover/history/romans/10-facts-about-the-ancient-romans/', 'content': 'i love this website\\nBIG BOBBY\\nbooby\\nI love shell my bae;)\\ni like bobby fishes ;0\\nI like turtles\\nOmg soy cool\\ngreeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatttttttttttttttttttttttt\\nbest fact ever\\nthis artical is cool\\nHANDY\\nrubbish did not help what so ever\\nha\\nRocking\\nTHIS IS THE BEST\\nproper rad in it cool\\nthis is cool\\nawesomeness\\nawsome\\nawsome\\nthank you captain\\nit is a lot of help\\ni like this\\nwebsite it helps me on my projects and isabel likes munier\\nmark uses this for research\\nlot of help\\nthis is awsome\\nTHE BEST BOOBOO\\nCool webpage helped me get 4 housepoints\\n This helped me A LOT on a school project\\ncool wow awesomoe\\nCOOL WEBSITE LOL\\nthis helped me with a school project :)\\nthat was awesome\\ncool\\nthat helped me out for my research test\\nReally its very cool really COOL\\nLIKE COOL best website so far its nice\\nI love it\\nnice facts\\nIt help with my history\\n i mean u made animaljam a awesome nice safe place for kids and this site to have kids a safe website to get facts for reports and stuff\\nLots of Love ,\\nRose\\npretty good website if u ask me\\nbut definently not gonna use it on a daily basis\\nIll try it again another time\\ngood\\nCool webcite\\nterrible\\nquite impressive\\nAwesome website it real helps\\nits good\\nthis is a great website! You really a lot with my project!:)\\nthis has helleped\\nme get\\nmy progect\\ndone\\nthank you\\nsoooooooooooooooooo\\nmuchchchchchch\\nthis helleped me\\nsooooooooo much with my progect thank you\\nvery good website\\nthank us very much your nice one today!!\\n'}, {'url': 'https://ohfact.com/roman-empire-facts/', 'content': 'Learn about the ancient Roman Civilization, its history, culture, army, architecture, food and more from this list of 27 facts. Discover how the Romans started, conquered, lived, died and influenced the world with their legends, myths and facts.'}, {'url': 'https://factnight.com/fun-facts-about-the-roman-empire/', 'content': 'The Roman Empire was one of the most influential and significant civilizations in world history. At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people. From its legendary beginnings and remarkable achievements to its eventual decline and fall, the Roman Empire is a fascinating topic full of little-known facts and intriguing trivia.'}, {'url': 'https://www.historyhit.com/facts-about-ancient-rome-and-the-romans/', 'content': 'The Enduring Legacy of C.S. Lewis\\nMargaret J. Winkler: A Forgotten Pioneer in Disney’s Success\\n10 Facts About Harper Lee\\nAntarctica Expedition Cruise\\nUncover Pompeii\\nSophie Hay and Tristan Hughes\\nRediscovering Richard III with Matt Lewis\\nOrder the History Hit Miscellany\\nHistory Hit Holidays\\nGift Subscriptions\\n100 Facts About Ancient Rome and the Romans\\nRome wasn’t built in a day, as the cliché reminds us. The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire\\nBarbarian factions, tribes and war leaders were now a factor in the power struggles at the top of Roman politics and one of the once-strong boundaries of the Empire had proved to be permeable.\\n Related Articles\\n10 Facts About Saint Andrew\\nThe Rise of Pompey the Great, the ‘Roman Alexander’\\nWatch and Listen\\nCleopatra\\nSex in Ancient Rome\\nRelated Locations\\nBaelo Claudia\\nMausoleum of Cecilia Metella\\nColin Ricketts\\n30 July 2021\\n By the fourth century BC, the story was accepted by Romans who were proud of their warrior founder\\nThe story was included in the first history of the city, by the Greek writer Diocles of Peparethus, and the twins and their wolf step-mother were depicted on Rome’s first coins.\\n The History Hit Miscellany of Facts, Figures and Fascinating Finds\\nA History of England: Part One\\nDragons: Myth & Reality\\nA Tudor Wonder - Hardwick Hall\\nThe Battle of Shrewsbury\\nEurope’s 1848 Revolutions\\nThe Boston Tea Party\\nHow Did 3 People Seemingly Escape From Alcatraz?\\n'}, {'url': 'https://www.countryfaq.com/facts-about-the-roman-empire/', 'content': 'Facts about the Roman Empire. Explore some of the interesting, fun, cool facts bout the Roman Empire: 1. The Magnificent Roman Empire. The Roman Empire, a colossal entity of unparalleled grandeur, occupies an indomitable position within the annals of human history, a name that resonates resoundingly across the eons.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,3,4,5\n", - "Cited Documents: 0,3,4,5\n", - "Answer: Here are some tips for writing an essay:\n", - "- Start with a question that spurs some response.\n", - "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", - "- You don't need a complete thesis, just a gap to explore.\n", - "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", - "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", - "- You can get breadth by reading and talking about a wide range of topics.\n", - "- You can get depth by doing and having to solve problems.\n", - "- You can also get ideas by talking to people who make you have new ideas.\n", - "\n", - "Here are some fun facts about the Roman Empire:\n", - "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", - "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", - "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\n", - "Grounded answer: Here are some tips for writing an essay:\n", - "- Start with a question that spurs some response.\n", - "- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\n", - "- You don't need a complete thesis, just a gap to explore.\n", - "- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\n", - "- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\n", - "- You can get breadth by reading and talking about a wide range of topics.\n", - "- You can get depth by doing and having to solve problems.\n", - "- You can also get ideas by talking to people who make you have new ideas.\n", - "\n", - "Here are some fun facts about the Roman Empire:\n", - "- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\n", - "- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\n", - "- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "\"Here are some tips for writing an essay:\\n- Start with a question that spurs some response.\\n- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\\n- You don't need a complete thesis, just a gap to explore.\\n- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\\n- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\\n- You can get breadth by reading and talking about a wide range of topics.\\n- You can get depth by doing and having to solve problems.\\n- You can also get ideas by talking to people who make you have new ideas.\\n\\nHere are some fun facts about the Roman Empire:\\n- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\\n- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\\n- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\"" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - } - }, - "metadata": {}, - "execution_count": 14 - } + "text/plain": [ + "\"Here are some tips for writing an essay:\\n- Start with a question that spurs some response.\\n- Don't choose a topic at random, make sure you have a way in, a new insight or approach.\\n- You don't need a complete thesis, just a gap to explore.\\n- You can get ideas by talking to people, reading, doing and building things, and going places and seeing things.\\n- You can improve the quality of your ideas by increasing the breadth and depth of what goes in.\\n- You can get breadth by reading and talking about a wide range of topics.\\n- You can get depth by doing and having to solve problems.\\n- You can also get ideas by talking to people who make you have new ideas.\\n\\nHere are some fun facts about the Roman Empire:\\n- At its peak, the empire stretched from North Africa to Britain, reigning over 60 million people.\\n- The story of Rome's warrior founder and the twins and their wolf step-mother was depicted on Rome's first coins.\\n- The Crossing of the Rhine in 405/6 AD brought around 100,000 barbarians into the Empire.\"" ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "DIP1YkXCg7rQ" - }, - "execution_count": 14, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "A question that requires the large language model to use a custom tool." - ], - "metadata": { - "id": "FhwS3VHvg3_l" - } - }, - { - "cell_type": "code", - "source": [ - "response = agent_executor.invoke({\n", - " \"input\": \"Calculate the result of the random operation of 10 and 20. Then find a few fun facts about that number, as well as its prime factors.\",\n", - " \"preamble\": preamble,\n", - "})\n", - "\n", - "response['output']\n", - "\n", - "# note that the model uses a sequence of tools" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 645 - }, - "id": "79Dw6Zhrg3xI", - "outputId": "a41c6de9-cb64-4cff-a58b-e9481d438f6c" + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"I want to write an essay about the Roman Empire. Any tips for writing an essay? Any fun facts?\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the model smartly looks in the vector db, and then online" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FhwS3VHvg3_l" + }, + "source": [ + "A question that requires the large language model to use a custom tool." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 645 + }, + "id": "79Dw6Zhrg3xI", + "outputId": "a41c6de9-cb64-4cff-a58b-e9481d438f6c" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "First, I will calculate the result of the random operation between 10 and 20. Then, I will search for fun facts about that number and its prime factors.\n", + "{'tool_name': 'random_operation_tool', 'parameters': {'a': 10, 'b': 20}}\n", + "\u001b[0mrandom_operation_tool is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3m\n", + "I received an error message when trying to use the random_operation_tool. I will now try using the python_interpreter tool to calculate the random operation between 10 and 20.\n", + "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import random\\n\\n# Define the two numbers\\na = 10\\nb = 20\\n\\n# Calculate the random operation\\nresult = random.choice(['+', '-', '*', '/'])\\n\\n# Perform the operation\\nif result == '+':\\n answer = a + b\\nelif result == '-':\\n answer = a - b\\nelif result == '*':\\n answer = a * b\\nelif result == '/':\\n answer = a / b\\n\\nprint(f'The result of the random operation is {answer:.0f}')\"}}\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mThe result of the random operation is 200\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "The result of the random operation is 200. Now I will search for fun facts about the number 200 and its prime factors.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the number 200'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.express.co.uk/life-style/top10facts/690340/Top-10-facts-number-200', 'content': \"Top 10 facts about the number 200 TODAY is the 200th day of 2016, so to celebrate let's have some facts about the number 200. By WILLIAM HARTSTON. 00:01, Mon, Jul 18, 2016.\"}, {'url': 'https://en.wikipedia.org/wiki/200_(number)', 'content': \"The number appears in the Padovan sequence, preceded by 86, 114, 151 (it is the sum of the first two of these). The sum of Euler's totient function φ(x) over the first twenty-five integers is 200. 200 is the smallest base 10 unprimeable number - it cannot be turned into a prime number by changing just one of its digits to any other digit.\"}, {'url': 'https://www.archimedes-lab.org/numbers/Num70_200.html', 'content': \"With 189 pages filled with an incredible variety of fun facts on numbers (and their peculiar properties), both mathematical and cultural, as well as tantalizing problems and anecdotes, there is much to learn for everyone. ... The number 200, according to Bullinger's study of biblical literature, signifies 'insufficiency'. The word 200 (ducenti) ...\"}, {'url': 'https://owlcation.com/misc/Over-200-Odd-Facts-Did-You-Know-Them', 'content': \"Over 200 odd facts about science, sports, history and more that you and your friends probably don't already know! ... Strange and Interesting Facts. ... Average number of people airborne over the U.S. at any given hour: 61,000. Portion of land in the U.S. owned by the government: 1/3. Ninety percent of New York City cabbies are recently arrived ...\"}, {'url': 'https://numbermatics.com/n/200/', 'content': 'Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. Your guide to the number 200, an even composite number composed of two distinct primes. Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. ... Number 200 - Facts about the integer. Retrieved 2 April ...'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'prime factors of 200'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.cuemath.com/numbers/factors-of-200/', 'content': 'Therefore, the factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, and 200. Which means the number 200 is an even composite number.'}, {'url': 'https://byjus.com/maths/factors-of-200/', 'content': \"The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200. Visit BYJU'S to learn the pair factors and the prime factors of 200 with complete\\xa0...\"}, {'url': 'https://byjus.com/us/math/factors-of-200/', 'content': 'The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200 because all these numbers divide the number 200 evenly.'}, {'url': 'https://homework.study.com/explanation/what-is-the-prime-factorization-of-200-using-exponents.html', 'content': 'The prime factorization of 200 using exponents is 2 3 ∗ 5 2 . First, we need to find the prime factorization of 200. 200 = 2 ∗ 100. 200 = 2 ∗ 2 ∗ 50.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,3,4,6,7,8,9,10\n", + "Cited Documents: 1,3,4,6,7,8,9,10\n", + "Answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", + "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", + "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", + "- The number 200 is an even composite number composed of two distinct primes.\n", + "\n", + "The prime factors of 200 are 2 and 5.\n", + "Grounded answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", + "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", + "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", + "- The number 200 is an even composite number composed of two distinct primes.\n", + "\n", + "The prime factors of 200 are 2 and 5.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" }, - "execution_count": 22, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "First, I will calculate the result of the random operation between 10 and 20. Then, I will search for fun facts about that number and its prime factors.\n", - "{'tool_name': 'random_operation_tool', 'parameters': {'a': 10, 'b': 20}}\n", - "\u001b[0mrandom_operation_tool is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3m\n", - "I received an error message when trying to use the random_operation_tool. I will now try using the python_interpreter tool to calculate the random operation between 10 and 20.\n", - "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import random\\n\\n# Define the two numbers\\na = 10\\nb = 20\\n\\n# Calculate the random operation\\nresult = random.choice(['+', '-', '*', '/'])\\n\\n# Perform the operation\\nif result == '+':\\n answer = a + b\\nelif result == '-':\\n answer = a - b\\nelif result == '*':\\n answer = a * b\\nelif result == '/':\\n answer = a / b\\n\\nprint(f'The result of the random operation is {answer:.0f}')\"}}\n", - "\u001b[0m\u001b[38;5;200m\u001b[1;3mThe result of the random operation is 200\n", - "\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "The result of the random operation is 200. Now I will search for fun facts about the number 200 and its prime factors.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'fun facts about the number 200'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.express.co.uk/life-style/top10facts/690340/Top-10-facts-number-200', 'content': \"Top 10 facts about the number 200 TODAY is the 200th day of 2016, so to celebrate let's have some facts about the number 200. By WILLIAM HARTSTON. 00:01, Mon, Jul 18, 2016.\"}, {'url': 'https://en.wikipedia.org/wiki/200_(number)', 'content': \"The number appears in the Padovan sequence, preceded by 86, 114, 151 (it is the sum of the first two of these). The sum of Euler's totient function φ(x) over the first twenty-five integers is 200. 200 is the smallest base 10 unprimeable number - it cannot be turned into a prime number by changing just one of its digits to any other digit.\"}, {'url': 'https://www.archimedes-lab.org/numbers/Num70_200.html', 'content': \"With 189 pages filled with an incredible variety of fun facts on numbers (and their peculiar properties), both mathematical and cultural, as well as tantalizing problems and anecdotes, there is much to learn for everyone. ... The number 200, according to Bullinger's study of biblical literature, signifies 'insufficiency'. The word 200 (ducenti) ...\"}, {'url': 'https://owlcation.com/misc/Over-200-Odd-Facts-Did-You-Know-Them', 'content': \"Over 200 odd facts about science, sports, history and more that you and your friends probably don't already know! ... Strange and Interesting Facts. ... Average number of people airborne over the U.S. at any given hour: 61,000. Portion of land in the U.S. owned by the government: 1/3. Ninety percent of New York City cabbies are recently arrived ...\"}, {'url': 'https://numbermatics.com/n/200/', 'content': 'Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. Your guide to the number 200, an even composite number composed of two distinct primes. Mathematical info, prime factorization, fun facts and numerical data for STEM, education and fun. ... Number 200 - Facts about the integer. Retrieved 2 April ...'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'prime factors of 200'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.cuemath.com/numbers/factors-of-200/', 'content': 'Therefore, the factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, and 200. Which means the number 200 is an even composite number.'}, {'url': 'https://byjus.com/maths/factors-of-200/', 'content': \"The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200. Visit BYJU'S to learn the pair factors and the prime factors of 200 with complete\\xa0...\"}, {'url': 'https://byjus.com/us/math/factors-of-200/', 'content': 'The factors of 200 are 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100 and 200 because all these numbers divide the number 200 evenly.'}, {'url': 'https://homework.study.com/explanation/what-is-the-prime-factorization-of-200-using-exponents.html', 'content': 'The prime factorization of 200 using exponents is 2 3 ∗ 5 2 . First, we need to find the prime factorization of 200. 200 = 2 ∗ 100. 200 = 2 ∗ 2 ∗ 50.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,3,4,6,7,8,9,10\n", - "Cited Documents: 1,3,4,6,7,8,9,10\n", - "Answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", - "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", - "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", - "- The number 200 is an even composite number composed of two distinct primes.\n", - "\n", - "The prime factors of 200 are 2 and 5.\n", - "Grounded answer: The result of the random operation is **200**. Here are some fun facts about the number 200:\n", - "- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\n", - "- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\n", - "- The number 200 is an even composite number composed of two distinct primes.\n", - "\n", - "The prime factors of 200 are 2 and 5.\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "\"The result of the random operation is **200**. Here are some fun facts about the number 200:\\n- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\\n- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\\n- The number 200 is an even composite number composed of two distinct primes.\\n\\nThe prime factors of 200 are 2 and 5.\"" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - } - }, - "metadata": {}, - "execution_count": 22 - } + "text/plain": [ + "\"The result of the random operation is **200**. Here are some fun facts about the number 200:\\n- It is the smallest base 10 unprimeable number, meaning it cannot be turned into a prime number by changing just one of its digits to any other digit.\\n- According to Bullinger's study of biblical literature, the number 200 signifies 'insufficiency'.\\n- The number 200 is an even composite number composed of two distinct primes.\\n\\nThe prime factors of 200 are 2 and 5.\"" ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "V8LcAh8vaEqR" - }, - "execution_count": 15, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "A question that requires the large language model to directly answer." - ], - "metadata": { - "id": "n9nV_jiaAaD1" - } - }, - { - "cell_type": "code", - "source": [ - "response = agent_executor.invoke({\n", - " \"input\": \"Hey how are you?\",\n", - " \"preamble\": preamble,\n", - "})\n", - "\n", - "response['output']\n", - "\n", - "# note that the modle can directly answer!" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 250 - }, - "id": "tRf6V3gJAZkO", - "outputId": "aec1acdb-876c-48e9-a1f5-e3ba8a0f19ed" + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"Calculate the result of the random operation of 10 and 20. Then find a few fun facts about that number, as well as its prime factors.\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the model uses a sequence of tools" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n9nV_jiaAaD1" + }, + "source": [ + "A question that requires the large language model to directly answer." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 250 + }, + "id": "tRf6V3gJAZkO", + "outputId": "aec1acdb-876c-48e9-a1f5-e3ba8a0f19ed" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will respond to the user's greeting.\n", + "{'tool_name': 'directly_answer', 'parameters': {}}\n", + "\u001b[0mdirectly_answer is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", + "Cited Documents: None\n", + "Answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\n", + "Grounded answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" }, - "execution_count": 23, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will respond to the user's greeting.\n", - "{'tool_name': 'directly_answer', 'parameters': {}}\n", - "\u001b[0mdirectly_answer is not a valid tool, try one of [internet_search, vectorstore_search, python_interpreter, random_operation].\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", - "Cited Documents: None\n", - "Answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\n", - "Grounded answer: I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "\"I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\"" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - } - }, - "metadata": {}, - "execution_count": 23 - } + "text/plain": [ + "\"I'm an AI chatbot, so I don't have feelings as such, but I'm here to help you with your queries. How can I help?\"" ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "hnLkln_ckYXJ" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## Ask a more complex question to the ReAct agent\n", - "A question that requires using multipe tools, in sequence" - ], - "metadata": { - "id": "3h-icRL2_5iu" - } - }, - { - "cell_type": "code", - "source": [ - "response = agent_executor.invoke({\n", - " \"input\": \"In what year was the company that was founded as Sound of Music went public? What was its stock price in 2000 and 2010.\",\n", - " \"preamble\": preamble,\n", - "})\n", - "\n", - "response['output']" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 377 - }, - "id": "Q4IyoXXRaEoL", - "outputId": "0e935f68-8b7c-4d9a-b8f1-1be57b7c9a1f" + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"Hey how are you?\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']\n", + "\n", + "# note that the modle can directly answer!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3h-icRL2_5iu" + }, + "source": [ + "## Ask a more complex question to the ReAct agent\n", + "A question that requires using multipe tools, in sequence" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 377 + }, + "id": "Q4IyoXXRaEoL", + "outputId": "0e935f68-8b7c-4d9a-b8f1-1be57b7c9a1f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for the company that was founded as Sound of Music. Then, I will search for the year it went public. Finally, I will search for its stock price in 2000 and 2010.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'company founded as Sound of Music'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.mprnews.org/story/2012/05/15/best-buy-richard-schulze-legacy', 'content': 'Amazon is taking a piece of everyone\\'s business,\"\\nSome analysts have questioned the extent to which Schulze\\'s strong hand over the company has held it back in the face of digital competition. \"\\nSchulze hit on the \"Best Buy\" strategy when a twister ripped open a store and the company held a huge sale with low prices and lots of promotion. And Richard Schulz was able to outthink and outmaneuver the competition to put up Best Buy as the definitive place in the brick-and-mortar world to buy electronic equipment,\" Spector said.\\n Best Buy\\'s Richard Schulze: Stereo seller to retail giant\\nShare\\nIn 1966, Best Buy was a stereo specialty retailer called Sound of Music, founded by Richard Schulze in St. Paul.\\n Former CEO Anderson said it is possible that Schulze\\'s goals for the company were out of touch with the digital age, and that Schulze may have stuck around too long.\\n'}, {'url': 'https://corporate.bestbuy.com/tag/sound-of-music/', 'content': 'As we celebrate Best Buy’s 50th anniversary, we sat down with founder and Chairman Emeritus Dick Schulze and current Chairman and CEO Hubert Joly to talk about how we got to where we are today and get a glimpse into where we’re going next.\\n Sound of Music\\n22 Aug: Best Buy at 50: A Q&A with Founder Dick Schulze and CEO Hubert Joly\\nTechnology has changed a lot over the past half century, and so has Best Buy.\\n 14 Jun: 35 Years Ago Today, A Tornado Transformed Best Buy\\nOn the afternoon of June 14, 1981, a tornado slammed into the Minneapolis suburbs, mere miles from where the Best Buy corporate headquarters now stands.\\n Little did he know that it would become Best Buy, a nearly $40 billion company that now sells everything from TVs and laptops to drones and virtual-reality headsets.\\n It was the most significant tornado to hit the Minneapolis-St. Paul area in 20 years — and its wake would change the path of our company.\\n'}, {'url': 'https://historydraft.com/story/best-buy/timeline/841', 'content': \"Best Buy announced the shutdown of the Future Shop chain in Canada\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.\\n Best Buy Company, Inc\\nIn 1983, with seven stores and $10 million in annual sales, Sound of Music was renamed Best Buy Company, Inc.\\nBest Buy debuted on the New York Stock Exchange\\nBest Buy was taken public in 1985, and two years later it debuted on the New York Stock Exchange.\\n The company closed all of its Best Buy-branded stores in China\\nThe company closed all of its Best Buy-branded stores in China by February 2011, when it merged Best Buy China's operations with Jiangsu Five Star, which had become a wholly-owned subsidiary of Best Buy in 2009.\\n Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores\\nIn July 2008, Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores, making the company the second-largest musical-instrument distributor in the US.\\n Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content\\nIn January 2004, Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content.\\n\"}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I have found that Best Buy was founded as Sound of Music. Now, I will search for the year it went public and its stock price in 2000 and 2010.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy went public'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.zippia.com/best-buy-careers-1455/history/', 'content': 'Meantime, Best Buy was taken public in 1985, raising $8 million through an IPO, and two years later gained a listing on the New York Stock Exchange (NYSE). ... Best Buy may also be known as or be related to Best Buy, Best Buy Co Inc, Best Buy Co., Inc., Sound of Music (1966-1983) Best Buy Co. Superstores (1983-1984) Best Buy Superstores ...'}, {'url': 'https://atouchofbusiness.com/companies/best-buy/', 'content': 'Public Listing and IPO: Best Buy went public in 1985 and listed on the NYSE in 1987. Conceptual Changes: The late 1980s and 1990s brought new store formats and growth, with revenues surpassing $1 billion. Overcoming Market Challenges. Supplier Relations: Mid-1990s challenges led to a merchandising revamp.'}, {'url': 'https://www.encyclopedia.com/social-sciences-and-law/economics-business-and-labor/businesses-and-occupations/best-buy-co-inc', 'content': 'Best Buy grew rapidly with $28.5 million in sales in 1984—compared to $9.9 million in 1983. In 1985, with 9 stores, Best Buy became a public company. By 1987, Best Buy had 24 stores and sales of $240 million, but it was beginning to feel the crunch as other rapidly expanding consumer electronics retailers pushed their way into the market.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy stock price in 2000 and 2010'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://finance.yahoo.com/quote/BBY/history/', 'content': 'Discover historical prices for BBY stock on Yahoo Finance. View daily, weekly or monthly format back to when Best Buy Co., Inc. stock was issued.'}, {'url': 'https://www.macrotrends.net/stocks/charts/BBY/best-buy/stock-price-history', 'content': 'Best Buy - 39 Year Stock Price History | BBY. Prices ... 2010, 25.1877, 25.7674, 31.2441, 20.2713, 22.3228 ... 2000, 16.0083, 15.2882, 22.8658, 5.9318, 7.8595, -\\xa0...'}, {'url': 'https://investors.bestbuy.com/investor-relations/stock-info/quote-and-chart/', 'content': 'Price 79.30. Change -0.88. Volume 666,622.'}, {'url': 'https://companiesmarketcap.com/best-buy/stock-price-history/', 'content': 'Stock price history for Best Buy (BBY). Highest end of day price: $138.00 USD on 2021-11-22. Lowest end of day price: $0.14 USD on 1985-05-02\\xa0...'}, {'url': 'https://www.netcials.com/stock-price-chart-history-nyse/BBY-Best-Buy-Co-Inc/', 'content': '1 Best Buy Co Inc (BBY) 20 Years Stock Chart History ; 2000, 16.24 (17.6%), 23.199 (29.07%) ; 2001, 14.80 (-8.87%), 20.1319 (-13.22%) ; 2002, 14.59 (-1.42%)\\xa0...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4,5,6,7,11,13,14\n", + "Cited Documents: 0,1,2,3,4,5,6,7,11,14\n", + "Answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\n", + "Grounded answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" }, - "execution_count": 27, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for the company that was founded as Sound of Music. Then, I will search for the year it went public. Finally, I will search for its stock price in 2000 and 2010.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'company founded as Sound of Music'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.mprnews.org/story/2012/05/15/best-buy-richard-schulze-legacy', 'content': 'Amazon is taking a piece of everyone\\'s business,\"\\nSome analysts have questioned the extent to which Schulze\\'s strong hand over the company has held it back in the face of digital competition. \"\\nSchulze hit on the \"Best Buy\" strategy when a twister ripped open a store and the company held a huge sale with low prices and lots of promotion. And Richard Schulz was able to outthink and outmaneuver the competition to put up Best Buy as the definitive place in the brick-and-mortar world to buy electronic equipment,\" Spector said.\\n Best Buy\\'s Richard Schulze: Stereo seller to retail giant\\nShare\\nIn 1966, Best Buy was a stereo specialty retailer called Sound of Music, founded by Richard Schulze in St. Paul.\\n Former CEO Anderson said it is possible that Schulze\\'s goals for the company were out of touch with the digital age, and that Schulze may have stuck around too long.\\n'}, {'url': 'https://corporate.bestbuy.com/tag/sound-of-music/', 'content': 'As we celebrate Best Buy’s 50th anniversary, we sat down with founder and Chairman Emeritus Dick Schulze and current Chairman and CEO Hubert Joly to talk about how we got to where we are today and get a glimpse into where we’re going next.\\n Sound of Music\\n22 Aug: Best Buy at 50: A Q&A with Founder Dick Schulze and CEO Hubert Joly\\nTechnology has changed a lot over the past half century, and so has Best Buy.\\n 14 Jun: 35 Years Ago Today, A Tornado Transformed Best Buy\\nOn the afternoon of June 14, 1981, a tornado slammed into the Minneapolis suburbs, mere miles from where the Best Buy corporate headquarters now stands.\\n Little did he know that it would become Best Buy, a nearly $40 billion company that now sells everything from TVs and laptops to drones and virtual-reality headsets.\\n It was the most significant tornado to hit the Minneapolis-St. Paul area in 20 years — and its wake would change the path of our company.\\n'}, {'url': 'https://historydraft.com/story/best-buy/timeline/841', 'content': \"Best Buy announced the shutdown of the Future Shop chain in Canada\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.\\n Best Buy Company, Inc\\nIn 1983, with seven stores and $10 million in annual sales, Sound of Music was renamed Best Buy Company, Inc.\\nBest Buy debuted on the New York Stock Exchange\\nBest Buy was taken public in 1985, and two years later it debuted on the New York Stock Exchange.\\n The company closed all of its Best Buy-branded stores in China\\nThe company closed all of its Best Buy-branded stores in China by February 2011, when it merged Best Buy China's operations with Jiangsu Five Star, which had become a wholly-owned subsidiary of Best Buy in 2009.\\n Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores\\nIn July 2008, Best Buy announced that it would start selling musical instruments and related gear in over 80 of its retail stores, making the company the second-largest musical-instrument distributor in the US.\\n Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content\\nIn January 2004, Best Buy hired Virtucom Group to revamp Best Buy's website and handle all of the company's online content.\\n\"}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "I have found that Best Buy was founded as Sound of Music. Now, I will search for the year it went public and its stock price in 2000 and 2010.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy went public'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.zippia.com/best-buy-careers-1455/history/', 'content': 'Meantime, Best Buy was taken public in 1985, raising $8 million through an IPO, and two years later gained a listing on the New York Stock Exchange (NYSE). ... Best Buy may also be known as or be related to Best Buy, Best Buy Co Inc, Best Buy Co., Inc., Sound of Music (1966-1983) Best Buy Co. Superstores (1983-1984) Best Buy Superstores ...'}, {'url': 'https://atouchofbusiness.com/companies/best-buy/', 'content': 'Public Listing and IPO: Best Buy went public in 1985 and listed on the NYSE in 1987. Conceptual Changes: The late 1980s and 1990s brought new store formats and growth, with revenues surpassing $1 billion. Overcoming Market Challenges. Supplier Relations: Mid-1990s challenges led to a merchandising revamp.'}, {'url': 'https://www.encyclopedia.com/social-sciences-and-law/economics-business-and-labor/businesses-and-occupations/best-buy-co-inc', 'content': 'Best Buy grew rapidly with $28.5 million in sales in 1984—compared to $9.9 million in 1983. In 1985, with 9 stores, Best Buy became a public company. By 1987, Best Buy had 24 stores and sales of $240 million, but it was beginning to feel the crunch as other rapidly expanding consumer electronics retailers pushed their way into the market.'}, {'url': 'https://www.company-histories.com/Best-Buy-Co-Inc-Company-History.html', 'content': 'As the Best Buy chain pushed past the 500-store mark in 2003 with the opening of 67 new stores in the United States, including the first stores in Alaska, Idaho, Utah, and West Virginia, the situation at the Musicland chains was deteriorating. Returning to the Core: 2003 and Beyond\\nDespite the completion of this acquisition, Best Buy pushed ahead with a previously planned expansion of the Best Buy chain into Canada, opening eight stores in the Toronto area in the fall of 2002. Significant changes were made to the product mix, particularly by eliminating slower selling product lines and models; a greater emphasis was placed on selling service plans to customers; and \"high touch\" areas were added to the stores to help sell the burgeoning array of digital consumer products, such as cameras, cellular phones, satellite systems, and the fast-selling DVD player (first introduced in 1996) for which customers often needed more assistance. This rapid growth in digital product sales also inspired a shift in the overall product mix: sales of consumer electronics products (33 percent of the total) surpassed the sales of home office products (31 percent) for the first time (in 1999 these figures were 27 percent and 36 percent, respectively). Magnolia was founded in 1954 by Len Tweten, who built the firm into one of the most respected audio-video retailers in the nation based on the high quality of its merchandise, its dedication to exceptional customer service, and its renowned in-house repair/installation department.'}, {'url': 'https://en.wikipedia.org/wiki/Best_Buy', 'content': 'Under the Geek Squad brand, Best Buy offers computer repair, warranty service, and accidental service plans.[2] Best Buy provides an online community forum for members, where consumers can discuss product experiences, ask questions, and get answers from other members or retail product experts.[82]\\nThe building exteriors of Best Buy-branded stores are typically light brown, with the entrance designed to look like a blue box emerging from the structure.[83] Corporate employees operated under a results only work environment from 2005 until March 2013, when the management style was abandoned by Best Buy CEO Hubert Joly.[84][85]\\nAs of October 29, 2016, Best Buy operated 1,026 Best Buy, 331 Best Buy Mobile stand-alone stores, and 28 stand-alone Pacific Sales stores in the US.[2] Best Buy also operated: 135 Best Buy and 53 Best Buy Mobile stand-alone stores in Canada; and 18 Best Buy stores and 5 Best Buy Express stores in Mexico.[2] Best Buy exited the European market in April 2013, selling its stake in the business back to its partner Carphone Warehouse.[71][72]\\nHouse brands[edit]\\nBest Buy also produces products under eight house brands:[2]\\nControversies[edit]\\nWarranty[edit]\\n The company, in announcing the result, said it was focusing more on digital media in its marketing, moving away from newspaper, magazine, and television advertising.[73]\\nOn March 28, 2015, Best Buy announced the shutdown of the Future Shop chain in Canada; 65 of its 131 former locations were converted into Best Buy locations, while the rest (primarily those in close proximity to an existing Best Buy) were closed permanently.[74]\\nOn March 1, 2018, the company announced that it would shut down its 250 standalone Best Buy Mobile stores in the United States by the end of May, due to low revenue and high costs. In August 2022, Best Buy said it would be laying off employees across the country after warnings of weaker sales, and the company cut its forecast for the remainder of 2022.[79]\\nOn October 13, 2023, Best Buy announced that it would phase out the sale of physical home media in early 2024, citing changes in the market due to the prevalence of streaming video on demand services.[80][81]\\nCorporate affairs[edit]\\nBusiness operations[edit]\\nBest Buy sells consumer electronics and a variety of related merchandise, including software, video games, music, mobile phones, digital cameras, car stereos, and video cameras, in addition to home appliances (washing machines, dryers, and refrigerators), in a noncommissioned sales environment.[2] The Best Buy Mobile stores were reported to account for 1% of the company\\'s revenue.[75]\\nOn May 9, 2018, the company unveiled a new logo for the first time in nearly three decades.[76]\\nOn July 2, 2018, Best Buy announced it was cutting the amount of store space devoted to selling physical music, citing the popularity of streaming services as having reduced sales.[77]\\nOn April 15, 2019, Best Buy announced that in June 2019, its current CFO, Corie Barry, would replace Hubert Joly[5] who held the position of CEO since August 2012. The customer was indicted for possession of child pornography, although the judge in the case later threw out nearly all the evidence against the defendant due to \"false and misleading statements\" made by an FBI agent while trying to secure a search warrant for the customer\\'s house, and the government ultimately dropped the case.[97]\\nPrivacy[edit]\\nOn October 20, 2023, CBC News released the results of a Marketplace investigation which found that that Best Buy technicians had viewed private files, such as intimate photos, on customer devices.'}]\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'Best Buy stock price in 2000 and 2010'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://finance.yahoo.com/quote/BBY/history/', 'content': 'Discover historical prices for BBY stock on Yahoo Finance. View daily, weekly or monthly format back to when Best Buy Co., Inc. stock was issued.'}, {'url': 'https://www.macrotrends.net/stocks/charts/BBY/best-buy/stock-price-history', 'content': 'Best Buy - 39 Year Stock Price History | BBY. Prices ... 2010, 25.1877, 25.7674, 31.2441, 20.2713, 22.3228 ... 2000, 16.0083, 15.2882, 22.8658, 5.9318, 7.8595, -\\xa0...'}, {'url': 'https://investors.bestbuy.com/investor-relations/stock-info/quote-and-chart/', 'content': 'Price 79.30. Change -0.88. Volume 666,622.'}, {'url': 'https://companiesmarketcap.com/best-buy/stock-price-history/', 'content': 'Stock price history for Best Buy (BBY). Highest end of day price: $138.00 USD on 2021-11-22. Lowest end of day price: $0.14 USD on 1985-05-02\\xa0...'}, {'url': 'https://www.netcials.com/stock-price-chart-history-nyse/BBY-Best-Buy-Co-Inc/', 'content': '1 Best Buy Co Inc (BBY) 20 Years Stock Chart History ; 2000, 16.24 (17.6%), 23.199 (29.07%) ; 2001, 14.80 (-8.87%), 20.1319 (-13.22%) ; 2002, 14.59 (-1.42%)\\xa0...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4,5,6,7,11,13,14\n", - "Cited Documents: 0,1,2,3,4,5,6,7,11,14\n", - "Answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\n", - "Grounded answer: Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "'Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.'" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - } - }, - "metadata": {}, - "execution_count": 27 - } + "text/plain": [ + "'Best Buy, which was founded as Sound of Music, went public in 1985. Its stock price in 2000 was between $5.93 and $16.24 and in 2010, it was between $20.27 and $31.24.'" ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "L1BsKueTaEmg" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## Have a multi-turn conversation with the ReAct agent\n", - "The chat history enables you to have multi-turn conversations with the ReAct agent." - ], - "metadata": { - "id": "53FDSFzQBFyf" - } - }, - { - "cell_type": "code", - "source": [ - "# Step 1: Construct the chat history as a list of LangChain Messages, ending with the last user message\n", - "from langchain_core.messages import HumanMessage, AIMessage\n", - "\n", - "chat_history = [\n", - " HumanMessage(content=\"I'm considering switching to Oracle for my CRM.\"),\n", - " AIMessage(content=\"That sounds like a good idea! How can I help you?\"),\n", - " HumanMessage(content=\"Recap me all the info you can find about their offering.\"),\n", - "]\n", - "\n", - "prompt = ChatPromptTemplate.from_messages(chat_history)" - ], - "metadata": { - "id": "1iYyAExsaEk9" - }, - "execution_count": 28, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "# Step 2: When you make the agent, specify the chat_history as the prompt, e.g.\n", - "# Create the ReAct agent\n", - "agent = create_cohere_react_agent(\n", - " llm=llm,\n", - " tools=[internet_search, vectorstore_search, python_tool],\n", - " prompt=prompt,\n", - ")\n", - "\n", - "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool], verbose=True)" - ], - "metadata": { - "id": "fyv_1LedaEi7" - }, - "execution_count": 29, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "# Step 3: When you invoke the agent_executor there's no need to pass anything else into invoke\n", - "response = agent_executor.invoke({\n", - " \"preamble\": preamble,\n", - "})\n", - "\n", - "response['output']" - ], - "metadata": { - "id": "-ZCFj-m5nqFw", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 538 - }, - "outputId": "3d71931e-1644-49b9-903c-4ff117787868" + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = agent_executor.invoke({\n", + " \"input\": \"In what year was the company that was founded as Sound of Music went public? What was its stock price in 2000 and 2010.\",\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "53FDSFzQBFyf" + }, + "source": [ + "## Have a multi-turn conversation with the ReAct agent\n", + "The chat history enables you to have multi-turn conversations with the ReAct agent." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "id": "1iYyAExsaEk9" + }, + "outputs": [], + "source": [ + "# Step 1: Construct the chat history as a list of LangChain Messages, ending with the last user message\n", + "from langchain_core.messages import HumanMessage, AIMessage\n", + "\n", + "chat_history = [\n", + " HumanMessage(content=\"I'm considering switching to Oracle for my CRM.\"),\n", + " AIMessage(content=\"That sounds like a good idea! How can I help you?\"),\n", + " HumanMessage(content=\"Recap me all the info you can find about their offering.\"),\n", + "]\n", + "\n", + "prompt = ChatPromptTemplate.from_messages(chat_history)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "id": "fyv_1LedaEi7" + }, + "outputs": [], + "source": [ + "# Step 2: When you make the agent, specify the chat_history as the prompt, e.g.\n", + "# Create the ReAct agent\n", + "agent = create_cohere_react_agent(\n", + " llm=llm,\n", + " tools=[internet_search, vectorstore_search, python_tool],\n", + " prompt=prompt,\n", + ")\n", + "\n", + "agent_executor = AgentExecutor(agent=agent, tools=[internet_search, vectorstore_search, python_tool], verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + }, + "id": "-ZCFj-m5nqFw", + "outputId": "3d71931e-1644-49b9-903c-4ff117787868" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for 'Oracle CRM offering' and relay the information I find to the user.\n", + "{'tool_name': 'internet_search', 'parameters': {'query': 'Oracle CRM offering'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://docs.oracle.com/en/applications/siebel/', 'content': 'Siebel CRM delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations. With solutions tailored to more than 20 industries, Siebel CRM delivers comprehensive on-premise CRM solutions that are tailored industry solutions with role-based customer intelligence and pre-built integration.'}, {'url': 'https://www.softwareadvice.com/resources/breaking-down-oracle-crm/', 'content': \"Oracle's Marketing Cloud provides a comprehensive set of tools that cover a range of digital marketing needs. This includes tools for cross-channel marketing, i.e., marketing automation for both B2B and B2C marketers, as well as data management, content marketing and social media marketing. Cross-Channel Marketing.\"}, {'url': 'https://www.trustradius.com/products/oracle-crm-on-demand/reviews?qs=pros-and-cons', 'content': \"What is Oracle CRM On Demand?The basis of this offering is the Market2Lead product that Oracle acquired in 2010. It has now been fully integrated with Oracle's On Demand CRM product and is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI.\"}, {'url': 'https://www.oracle.com/cx/siebel/', 'content': 'In addition to standard CRM functionality, this industry solution includes asset, premises, and contracts management; work orders; oil well management and oil field service; B2C and B2B web portals; and credit and fraud management capabilities.\\nDesigned for pharmaceutical sales, Siebel CRM Life Sciences provides personalized content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction.\\n Marketing, sales, and customer service applications are fully integrated and designed to manage the complex interactions and relationships between brand owners, their partners (including brokers and distributors), their customers, and the end consumer.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n Provide world-class citizen services while delivering comprehensive, cost-efficient case management and policy management, including social services, justice and public safety, constituent services/311, self-service citizen portals, tax and revenue, and licensing and permitting.\\n'}, {'url': 'https://www.suretysystems.com/insights/oracle-customer-relationship-management-a-complete-overview/', 'content': 'Effective CRM systems offer the following features for enterprise users: Simple, easy-to-use interface; ... Oracle CRM simplifies customer relationship management by enhancing customer interactions and improving customer satisfaction and sales growth. Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM ...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4\n", + "Cited Documents: 0,1,2,3,4\n", + "Answer: Oracle's CRM offering includes the following:\n", + "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", + "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", + "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", + "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", + "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\n", + "Grounded answer: Oracle's CRM offering includes the following:\n", + "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", + "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", + "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", + "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", + "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" }, - "execution_count": 30, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for 'Oracle CRM offering' and relay the information I find to the user.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'Oracle CRM offering'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://docs.oracle.com/en/applications/siebel/', 'content': 'Siebel CRM delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations. With solutions tailored to more than 20 industries, Siebel CRM delivers comprehensive on-premise CRM solutions that are tailored industry solutions with role-based customer intelligence and pre-built integration.'}, {'url': 'https://www.softwareadvice.com/resources/breaking-down-oracle-crm/', 'content': \"Oracle's Marketing Cloud provides a comprehensive set of tools that cover a range of digital marketing needs. This includes tools for cross-channel marketing, i.e., marketing automation for both B2B and B2C marketers, as well as data management, content marketing and social media marketing. Cross-Channel Marketing.\"}, {'url': 'https://www.trustradius.com/products/oracle-crm-on-demand/reviews?qs=pros-and-cons', 'content': \"What is Oracle CRM On Demand?The basis of this offering is the Market2Lead product that Oracle acquired in 2010. It has now been fully integrated with Oracle's On Demand CRM product and is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI.\"}, {'url': 'https://www.oracle.com/cx/siebel/', 'content': 'In addition to standard CRM functionality, this industry solution includes asset, premises, and contracts management; work orders; oil well management and oil field service; B2C and B2B web portals; and credit and fraud management capabilities.\\nDesigned for pharmaceutical sales, Siebel CRM Life Sciences provides personalized content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction.\\n Marketing, sales, and customer service applications are fully integrated and designed to manage the complex interactions and relationships between brand owners, their partners (including brokers and distributors), their customers, and the end consumer.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n It leverages data and AI to transform CX–launching offers, acquiring and retaining customers, omnichannel ecommerce and customer care, and fulfilling and monetizing services.\\n Provide world-class citizen services while delivering comprehensive, cost-efficient case management and policy management, including social services, justice and public safety, constituent services/311, self-service citizen portals, tax and revenue, and licensing and permitting.\\n'}, {'url': 'https://www.suretysystems.com/insights/oracle-customer-relationship-management-a-complete-overview/', 'content': 'Effective CRM systems offer the following features for enterprise users: Simple, easy-to-use interface; ... Oracle CRM simplifies customer relationship management by enhancing customer interactions and improving customer satisfaction and sales growth. Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM ...'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4\n", - "Cited Documents: 0,1,2,3,4\n", - "Answer: Oracle's CRM offering includes the following:\n", - "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", - "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", - "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", - "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", - "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\n", - "Grounded answer: Oracle's CRM offering includes the following:\n", - "- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\n", - "- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\n", - "- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\n", - "- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\n", - "- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "\"Oracle's CRM offering includes the following:\\n- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\\n- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\\n- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\\n- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\\n- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\"" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - } - }, - "metadata": {}, - "execution_count": 30 - } + "text/plain": [ + "\"Oracle's CRM offering includes the following:\\n- Marketing Cloud, which provides a comprehensive set of tools that cover a range of digital marketing needs, including cross-channel marketing, marketing automation, data management, content marketing and social media marketing\\n- CRM On Demand, which is a full-featured marketing automation product with features from lead management and nurturing, to measuring marketing ROI\\n- Siebel CRM, which delivers a combination of transactional, analytical, and engagement features to manage all customer-facing operations, with solutions tailored to more than 20 industries\\n- Siebel CRM Life Sciences, which provides personalised content delivery tools to help sales and marketing teams deliver the right messages during each customer interaction\\n- Oracle Client Experience (CX), a connected suite of tools that transcends standard CRM\"" ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "8Zh01M4hWw3L" - }, - "execution_count": 30, - "outputs": [] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "0qEPY6xj_qwr" - }, - "execution_count": null, - "outputs": [] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" } - ] -} \ No newline at end of file + ], + "source": [ + "# Step 3: When you invoke the agent_executor there's no need to pass anything else into invoke\n", + "response = agent_executor.invoke({\n", + " \"preamble\": preamble,\n", + "})\n", + "\n", + "response['output']" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "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.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/agents/Vanilla_Tool_Use.ipynb b/notebooks/agents/Vanilla_Tool_Use.ipynb index 26aa6fdc..69d21c5c 100644 --- a/notebooks/agents/Vanilla_Tool_Use.ipynb +++ b/notebooks/agents/Vanilla_Tool_Use.ipynb @@ -1,674 +1,631 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - " \"Open\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "YN-eakfxtLGd" - }, - "source": [ - "# Tool Use\n", - "\n", - "Tool use allows customers to **connect their large language models to external tools like search engines, APIs, functions, databases**, etc.\n", - "\n", - "This allows the customer's model to unlock a richer set of behaviors by leveraging data stored in tools, taking actions through APIs, interacting with a vector database, querying a search engine, etc.\n", - "\n", - "This is particularly valuable for enterprise customers, since a lot of enterprise data lives in external sources.\n", - "\n", - "Tool Use consists of 4 steps:\n", - "- Step 1: the user configures the request to the model\n", - "- Step 2: the **model smartly decides which tool(s) to use and how**\n", - "- Step 3: the tool calls are executed to mock database\n", - "- Step 4: the **model generates a final answer with precise citations based on the tool results**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "us5dkKrLCbXW", - "outputId": "94c97f62-77fb-4492-a4e4-d9eeee4e438c" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m28.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ], - "source": [ - "# we'll use Cohere to do Tool Use\n", - "# TODO: upgrade to \"cohere>5\"\n", - "%pip install \"cohere<5\" --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "j0DC3iPftLGo" - }, - "outputs": [], - "source": [ - "import cohere, json\n", - "API_KEY = \"...\" # fill in your Cohere API key here\n", - "co = cohere.Client(API_KEY)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0T7yc1PltLGp" - }, - "source": [ - "## Step 0: Create a mock database\n", - "First, we'll define the mock data that our tools will query. This data represents sales reports and a product catalog." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "yZffY8xItLGp" - }, - "outputs": [], - "source": [ - "# Mock database containing daily sales reports\n", - "sales_database = {\n", - " '2023-09-28': {\n", - " 'total_sales_amount': 5000,\n", - " 'total_units_sold': 100,\n", - " },\n", - " '2023-09-29': {\n", - " 'total_sales_amount': 10000,\n", - " 'total_units_sold': 250,\n", - " },\n", - " '2023-09-30': {\n", - " 'total_sales_amount': 8000,\n", - " 'total_units_sold': 200,\n", - " }\n", - "}\n", - "\n", - "# Mock product catalog\n", - "product_catalog = {\n", - " 'Electronics': [\n", - " {'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20},\n", - " {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15},\n", - " {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25},\n", - " ],\n", - " 'Clothing': [\n", - " {'product_id': 'C1001', 'name': 'T-Shirt', 'price': 20, 'stock_level': 100},\n", - " {'product_id': 'C1002', 'name': 'Jeans', 'price': 50, 'stock_level': 80},\n", - " {'product_id': 'C1003', 'name': 'Jacket', 'price': 100, 'stock_level': 40},\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "6TGWYiOdtLGp" - }, - "source": [ - "Now, we'll define the tools that simulate querying this database. \n", - "You could for example use the API of an enterprise sales platform.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "YuIH4us8tLGp" - }, - "outputs": [], - "source": [ - "def query_daily_sales_report(day: str) -> dict:\n", - " \"\"\"\n", - " Function to retrieve the sales report for the given day\n", - " \"\"\"\n", - " report = sales_database.get(day, {})\n", - " if report:\n", - " return {\n", - " 'date': day,\n", - " 'summary': f\"Total Sales Amount: {report['total_sales_amount']}, Total Units Sold: {report['total_units_sold']}\"\n", - " }\n", - " else:\n", - " return {'date': day, 'summary': 'No sales data available for this day.'}\n", - "\n", - "\n", - "def query_product_catalog(category: str) -> dict:\n", - " \"\"\"\n", - " Function to retrieve products for the given category\n", - " \"\"\"\n", - " products = product_catalog.get(category, [])\n", - " return {\n", - " 'category': category,\n", - " 'products': products\n", - " }\n", - "\n", - "\n", - "functions_map = {\n", - " \"query_daily_sales_report\": query_daily_sales_report,\n", - " \"query_product_catalog\": query_product_catalog\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "HZRhTu4ftLGp" - }, - "source": [ - "## Step 1 - the user configures the request to the model\n", - "\n", - "The developer provides a few things to the model:\n", - "- A preamble containing instructions about the task and the desired style for the output.\n", - "- The user request.\n", - "- A list of tools to the model.\n", - "- (Optionally) a chat history for the model to work with.\n", - "\n", - "\n", - "You can specify one or many tools to the model. Every tool needs to be described with a JSON schema, indicating the tool name, description, and parameters (code snippets below).\n", - "\n", - "In our example, we provide two tools to the model: `daily_sales_report` and `product_catalog`.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "aIk-of_OtLGp" - }, - "outputs": [], - "source": [ - "# tool descriptions that the model has access to\n", - "# note: Cohere always adds a \"directly_answer\" tool under the hood, so that the model can decide to not leverage any tool, if they're not needed.\n", - "tools = [\n", - " {\n", - " \"name\": \"query_daily_sales_report\",\n", - " \"description\": \"Connects to a database to retrieve overall sales volumes and sales information for a given day.\",\n", - " \"parameter_definitions\": {\n", - " \"day\": {\n", - " \"description\": \"Retrieves sales data for this day, formatted as YYYY-MM-DD.\",\n", - " \"type\": \"str\",\n", - " \"required\": True\n", - " }\n", - " }\n", - " },\n", - " {\n", - " \"name\": \"query_product_catalog\",\n", - " \"description\": \"Connects to a a product catalog with information about all the products being sold, including categories, prices, and stock levels.\",\n", - " \"parameter_definitions\": {\n", - " \"category\": {\n", - " \"description\": \"Retrieves product information data for all products in this category.\",\n", - " \"type\": \"str\",\n", - " \"required\": True\n", - " }\n", - " }\n", - " }\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "k2AHJRnztLGp" - }, - "source": [ - "Now let's define the user request. \n", - "\n", - "In our example we'll use: \"Can you provide a sales summary for 29th September 2023, and also give me the details of all products in the 'Electronics' category that were sold that day, including their prices and stock levels?\"\n", - "\n", - "Only a langage model with Tool Use can answer this request: it requires looking up information in the right external tools (step 2), and then providing a final answer based on the tool results (step 4)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "JuDgJ7fjtLGq" - }, - "outputs": [], - "source": [ - "# preamble containing instructions about the task and the desired style for the output.\n", - "preamble = \"\"\"\n", - "## Task & Context\n", - "You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n", - "\n", - "## Style Guide\n", - "Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\n", - "\"\"\"\n", - "\n", - "# user request\n", - "message = \"Can you provide a sales summary for 29th September 2023, and also give me some details about the products in the 'Electronics' category, for example their prices and stock levels?\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "1NhW-G_JtLGq" - }, - "source": [ - "## Step 2 – the model smartly decides which tool(s) to use and how\n", - "The model intelligently selects the right tool(s) to call -- and the right parameters for each tool call -- based on the content of the user message." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "o79_n99GtLGq", - "outputId": "81789d00-01b9-4c17-d1b0-1668d75a2b86" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The model recommends doing the following tool calls:\n", - "cohere.ToolCall {\n", - "\tname: query_daily_sales_report\n", - "\tparameters: {'day': '2023-09-29'}\n", - "\tgeneration_id: eaf955e3-623d-4796-bf51-23b07c66ed2c\n", - "}\n", - "cohere.ToolCall {\n", - "\tname: query_product_catalog\n", - "\tparameters: {'category': 'Electronics'}\n", - "\tgeneration_id: eaf955e3-623d-4796-bf51-23b07c66ed2c\n", - "}\n" - ] - } - ], - "source": [ - "response = co.chat(\n", - " message=message,\n", - " tools=tools,\n", - " preamble=preamble,\n", - " model=\"command-r\"\n", - ")\n", - "\n", - "# Note that the Cohere Chat API also exposes:\n", - "# - stream (for streaming mode)\n", - "# - chat_history\n", - "# - among other parameters\n", - "# See https://docs.cohere.com/reference/chat for details.\n", - "\n", - "print(\"The model recommends doing the following tool calls:\")\n", - "print(\"\\n\".join(str(tool_call) for tool_call in response.tool_calls))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "md_9QPcxtLGq" - }, - "source": [ - "## Step 3 – the tool calls are executed\n", - "\n", - "You can then execute the appropriate calls, using the tool calls and tool parameters generated by the model. \n", - "These tool calls return tool results that will be fed to the model in Step 4." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "1LuDCRpFtLGr", - "outputId": "42ead35e-225a-4b9a-c954-b526f2865350" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "= running tool query_daily_sales_report, with parameters: {'day': '2023-09-29'}\n", - "== tool results: [{'date': '2023-09-29', 'summary': 'Total Sales Amount: 10000, Total Units Sold: 250'}]\n", - "= running tool query_product_catalog, with parameters: {'category': 'Electronics'}\n", - "== tool results: [{'category': 'Electronics', 'products': [{'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20}, {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15}, {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25}]}]\n", - "Tool results that will be fed back to the model in step 4:\n", - "[\n", - " {\n", - " \"call\": {\n", - " \"name\": \"query_daily_sales_report\",\n", - " \"parameters\": {\n", - " \"day\": \"2023-09-29\"\n", - " },\n", - " \"generation_id\": \"eaf955e3-623d-4796-bf51-23b07c66ed2c\"\n", - " },\n", - " \"outputs\": [\n", - " {\n", - " \"date\": \"2023-09-29\",\n", - " \"summary\": \"Total Sales Amount: 10000, Total Units Sold: 250\"\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"call\": {\n", - " \"name\": \"query_product_catalog\",\n", - " \"parameters\": {\n", - " \"category\": \"Electronics\"\n", - " },\n", - " \"generation_id\": \"eaf955e3-623d-4796-bf51-23b07c66ed2c\"\n", - " },\n", - " \"outputs\": [\n", - " {\n", - " \"category\": \"Electronics\",\n", - " \"products\": [\n", - " {\n", - " \"product_id\": \"E1001\",\n", - " \"name\": \"Smartphone\",\n", - " \"price\": 500,\n", - " \"stock_level\": 20\n", - " },\n", - " {\n", - " \"product_id\": \"E1002\",\n", - " \"name\": \"Laptop\",\n", - " \"price\": 1000,\n", - " \"stock_level\": 15\n", - " },\n", - " {\n", - " \"product_id\": \"E1003\",\n", - " \"name\": \"Tablet\",\n", - " \"price\": 300,\n", - " \"stock_level\": 25\n", - " }\n", - " ]\n", - " }\n", - " ]\n", - " }\n", - "]\n" - ] - } - ], - "source": [ - "tool_results = []\n", - "# Iterate over the tool calls generated by the model\n", - "for tool_call in response.tool_calls:\n", - " # here is where you would call the tool recommended by the model, using the parameters recommended by the model\n", - " print(f\"= running tool {tool_call.name}, with parameters: {tool_call.parameters}\")\n", - " output = functions_map[tool_call.name](**tool_call.parameters)\n", - " # store the output in a list\n", - " outputs = [output]\n", - " print(f\"== tool results: {outputs}\")\n", - " # store your tool results in this format\n", - " tool_results.append({\n", - " \"call\": tool_call,\n", - " \"outputs\": outputs\n", - " })\n", - "\n", - "print(\"Tool results that will be fed back to the model in step 4:\")\n", - "print(json.dumps(tool_results, indent=4))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8cKlLk18tLGr" - }, - "source": [ - "## Step 4 - the model generates a final answer based on the tool results\n", - "Finally, the developer calls the Cohere model, providing the tools results, in order to generate the model's final answer. \n", - "\n", - "Bonus: At Cohere, all Tool Use calls come with... **precise citations**! 🎉\n", - "The model cites which tool results were used to generate the final answer. \n", - "These citations make it easy to check where the model’s generated response claims are coming from. \n", - "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", - "These citations are optional — you can decide to ignore them.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "MKnjXVfXtLGr" - }, - "outputs": [], - "source": [ - "response = co.chat(\n", - " message=message,\n", - " tools=tools,\n", - " tool_results=tool_results,\n", - " preamble=preamble,\n", - " model=\"command-r\",\n", - " temperature=0.3\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "jlxKTsaztLGr", - "outputId": "b2cd8667-bca9-4928-c423-61930b4b49fa" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Final answer:\n", - "On the 29th of September 2023, there were 10,000 sales with 250 units sold. \n", - "\n", - "The Electronics category contains three products. There are details below:\n", - "\n", - "| Product Name | Price | Stock Level |\n", - "| ------------ | ----- | ----------- |\n", - "| Smartphone | 500 | 20 |\n", - "| Laptop | 1000 | 15 |\n", - "| Tablet | 300 | 25 | \n", - "\n", - "The total stock level for Electronics items is 50.\n" - ] - } - ], - "source": [ - "print(\"Final answer:\")\n", - "print(response.text)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "niMkAr2PN9j4" - }, - "source": [ - "## Bonus: Citations come for free with Cohere! 🎉\n", - "\n", - "At Cohere, model generations come with... precise citations! 🎉\n", - "The model cites which groups of words, in the tool results, were used to generate the final answer. \n", - "These citations make it easy to check where the model’s generated response claims are coming from. \n", - "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", - "These citations are optional — you can decide to ignore them." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + " \"Open\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YN-eakfxtLGd" + }, + "source": [ + "# Basic Tool Use\n", + "\n", + "Tool use allows customers to **connect their large language models to external tools, such as search engines, APIs, functions, and databases**.\n", + "\n", + "This allows the customer to unlock a richer set of model behaviors by, for instance, leveraging data stored in tools, taking actions through APIs, interacting with a vector database, or querying a search engine.\n", + "\n", + "Below, we illustrate tool use in four steps:\n", + "- Step 1: the user configures the request to the model\n", + "- Step 2: the model uses context to **determine which tool(s) to use and how**\n", + "- Step 3: the tool calls are executed\n", + "- Step 4: the model **generates a final answer with precise citations** based on the tool results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "j0DC3iPftLGo" + }, + "outputs": [], + "source": [ + "import cohere, json\n", + "API_KEY = \"...\" # fill in your Cohere API key here\n", + "co = cohere.Client(API_KEY)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0T7yc1PltLGp" + }, + "source": [ + "## Step 0: Create a mock database\n", + "\n", + "Before we can illustrate tool use, we first need to do some setup. Here, we'll define the mock data that our tools will query. This data represents sales reports and a product catalog." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yZffY8xItLGp" + }, + "outputs": [], + "source": [ + "# Mock database containing daily sales reports\n", + "sales_database = {\n", + " '2023-09-28': {\n", + " 'total_sales_amount': 5000,\n", + " 'total_units_sold': 100,\n", + " },\n", + " '2023-09-29': {\n", + " 'total_sales_amount': 10000,\n", + " 'total_units_sold': 250,\n", + " },\n", + " '2023-09-30': {\n", + " 'total_sales_amount': 8000,\n", + " 'total_units_sold': 200,\n", + " }\n", + "}\n", + "\n", + "# Mock product catalog\n", + "product_catalog = {\n", + " 'Electronics': [\n", + " {'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20},\n", + " {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15},\n", + " {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25},\n", + " ],\n", + " 'Clothing': [\n", + " {'product_id': 'C1001', 'name': 'T-Shirt', 'price': 20, 'stock_level': 100},\n", + " {'product_id': 'C1002', 'name': 'Jeans', 'price': 50, 'stock_level': 80},\n", + " {'product_id': 'C1003', 'name': 'Jacket', 'price': 100, 'stock_level': 40},\n", + " ]\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6TGWYiOdtLGp" + }, + "source": [ + "Now, we'll define the tools that simulate querying this database. \n", + "For example, you could use the API of an enterprise sales platform.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YuIH4us8tLGp", + "tags": [] + }, + "outputs": [], + "source": [ + "def query_daily_sales_report(day: str) -> dict:\n", + " \"\"\"\n", + " Function to retrieve the sales report for the given day\n", + " \"\"\"\n", + " report = sales_database.get(day, {})\n", + " if report:\n", + " return {\n", + " 'date': day,\n", + " 'summary': f\"Total Sales Amount: {report['total_sales_amount']}, Total Units Sold: {report['total_units_sold']}\"\n", + " }\n", + " else:\n", + " return {'date': day, 'summary': 'No sales data available for this day.'}\n", + "\n", + "\n", + "def query_product_catalog(category: str) -> dict:\n", + " \"\"\"\n", + " Function to retrieve products for the given category\n", + " \"\"\"\n", + " products = product_catalog.get(category, [])\n", + " return {\n", + " 'category': category,\n", + " 'products': products\n", + " }\n", + "\n", + "\n", + "functions_map = {\n", + " \"query_daily_sales_report\": query_daily_sales_report,\n", + " \"query_product_catalog\": query_product_catalog\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HZRhTu4ftLGp" + }, + "source": [ + "## Step 1 - User configures the request to the model\n", + "\n", + "The developer provides a few things to the model:\n", + "- A preamble containing instructions about the task and the desired style for the output.\n", + "- The user request.\n", + "- A list of tools to the model.\n", + "- (Optionally) a chat history for the model to work with.\n", + "\n", + "\n", + "You can specify one or many tools to the model. Every tool needs to be described with a JSON schema, indicating the tool name, description, and parameters (code snippets below).\n", + "\n", + "In our example, we provide two tools to the model: `daily_sales_report` and `product_catalog`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "aIk-of_OtLGp" + }, + "outputs": [], + "source": [ + "# tool descriptions that the model has access to\n", + "# note: Cohere always adds a \"directly_answer\" tool under the hood, so that the model can decide to not leverage any tool, if they're not needed.\n", + "tools = [\n", + " {\n", + " \"name\": \"query_daily_sales_report\",\n", + " \"description\": \"Connects to a database to retrieve overall sales volumes and sales information for a given day.\",\n", + " \"parameter_definitions\": {\n", + " \"day\": {\n", + " \"description\": \"Retrieves sales data for this day, formatted as YYYY-MM-DD.\",\n", + " \"type\": \"str\",\n", + " \"required\": True\n", + " }\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"query_product_catalog\",\n", + " \"description\": \"Connects to a a product catalog with information about all the products being sold, including categories, prices, and stock levels.\",\n", + " \"parameter_definitions\": {\n", + " \"category\": {\n", + " \"description\": \"Retrieves product information data for all products in this category.\",\n", + " \"type\": \"str\",\n", + " \"required\": True\n", + " }\n", + " }\n", + " }\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "k2AHJRnztLGp" + }, + "source": [ + "Now let's define the user request. \n", + "\n", + "In our example we'll use: \"Can you provide a sales summary for 29th September 2023, and also give me the details of all products in the 'Electronics' category that were sold that day, including their prices and stock levels?\"\n", + "\n", + "Only a langage model with Tool Use can answer this request: it requires looking up information in the right external tools (step 2), and then providing a final answer based on the tool results (step 4)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JuDgJ7fjtLGq" + }, + "outputs": [], + "source": [ + "# preamble containing instructions about the task and the desired style for the output.\n", + "preamble = \"\"\"\n", + "## Task & Context\n", + "You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n", + "\n", + "## Style Guide\n", + "Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\n", + "\"\"\"\n", + "\n", + "# user request\n", + "message = \"Can you provide a sales summary for 29th September 2023, and also give me some details about the products in the 'Electronics' category, for example their prices and stock levels?\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1NhW-G_JtLGq" + }, + "source": [ + "## Step 2 – The model smartly decides which tool(s) to use and how\n", + "The model intelligently selects the right tool(s) to call -- and the right parameters for each tool call -- based on the content of the user message." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "o79_n99GtLGq", + "outputId": "81789d00-01b9-4c17-d1b0-1668d75a2b86" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "9wuoCUBwtLGr", - "outputId": "da3c0dc5-6b87-42ea-d64b-e7e85c40273e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Citations that support the final answer:\n", - "{'start': 7, 'end': 29, 'text': '29th of September 2023', 'document_ids': ['query_daily_sales_report:0:0']}\n", - "{'start': 42, 'end': 75, 'text': '10,000 sales with 250 units sold.', 'document_ids': ['query_daily_sales_report:0:0']}\n", - "{'start': 112, 'end': 127, 'text': 'three products.', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 234, 'end': 244, 'text': 'Smartphone', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 247, 'end': 250, 'text': '500', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 253, 'end': 255, 'text': '20', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 260, 'end': 266, 'text': 'Laptop', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 269, 'end': 273, 'text': '1000', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 276, 'end': 278, 'text': '15', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 283, 'end': 289, 'text': 'Tablet', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 292, 'end': 295, 'text': '300', 'document_ids': ['query_product_catalog:1:0']}\n", - "{'start': 298, 'end': 300, 'text': '25', 'document_ids': ['query_product_catalog:1:0']}\n" - ] - } - ], - "source": [ - "print(\"Citations that support the final answer:\")\n", - "for cite in response.citations:\n", - " print(cite)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "The model recommends doing the following tool calls:\n", + "cohere.ToolCall {\n", + "\tname: query_daily_sales_report\n", + "\tparameters: {'day': '2023-09-29'}\n", + "\tgeneration_id: eaf955e3-623d-4796-bf51-23b07c66ed2c\n", + "}\n", + "cohere.ToolCall {\n", + "\tname: query_product_catalog\n", + "\tparameters: {'category': 'Electronics'}\n", + "\tgeneration_id: eaf955e3-623d-4796-bf51-23b07c66ed2c\n", + "}\n" + ] + } + ], + "source": [ + "response = co.chat(\n", + " message=message,\n", + " tools=tools,\n", + " preamble=preamble,\n", + " model=\"command-r\"\n", + ")\n", + "\n", + "# Note that the Cohere Chat API also exposes:\n", + "# - stream (for streaming mode)\n", + "# - chat_history\n", + "# - among other parameters\n", + "# See https://docs.cohere.com/reference/chat for details.\n", + "\n", + "print(\"The model recommends doing the following tool calls:\")\n", + "print(\"\\n\".join(str(tool_call) for tool_call in response.tool_calls))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "md_9QPcxtLGq" + }, + "source": [ + "## Step 3 – The tool calls are executed\n", + "\n", + "You can now execute the appropriate calls, using the tool calls and tool parameters generated by the model. \n", + "These tool calls return tool results that will be fed to the model in Step 4." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "1LuDCRpFtLGr", + "outputId": "42ead35e-225a-4b9a-c954-b526f2865350" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "7td1J80DOKTM", - "outputId": "e6e4fa7d-67eb-42ca-e736-9a45a47a6c1d" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "On the **29th of September 2023**[1], there were **10,000 sales with 250 units sold.**[1] \n", - "\n", - "The Electronics category contains **three products.**[2] There are details below:\n", - "\n", - "| Product Name | Price | Stock Level |\n", - "| ------------ | ----- | ----------- |\n", - "| **Smartphone**[2] | **500**[2] | **20**[2] |\n", - "| **Laptop**[2] | **1000**[2] | **15**[2] |\n", - "| **Tablet**[2] | **300**[2] | **25**[2] | \n", - "\n", - "The total stock level for Electronics items is 50.\n", - "\n", - "[1] source: [{'date': '2023-09-29', 'summary': 'Total Sales Amount: 10000, Total Units Sold: 250'}] \n", - " based on tool call: {'name': 'query_daily_sales_report', 'parameters': {'day': '2023-09-29'}, 'generation_id': 'eaf955e3-623d-4796-bf51-23b07c66ed2c'}\n", - "[2] source: [{'category': 'Electronics', 'products': [{'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20}, {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15}, {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25}]}] \n", - " based on tool call: {'name': 'query_product_catalog', 'parameters': {'category': 'Electronics'}, 'generation_id': 'eaf955e3-623d-4796-bf51-23b07c66ed2c'}\n" - ] - } - ], - "source": [ - "def insert_citations_in_order(text, citations):\n", - " \"\"\"\n", - " A helper function to pretty print citations.\n", - " \"\"\"\n", - " offset = 0\n", - " document_id_to_number = {}\n", - " citation_number = 0\n", - " modified_citations = []\n", - "\n", - " # Process citations, assigning numbers based on unique document_ids\n", - " for citation in citations:\n", - " citation_numbers = []\n", - " for document_id in sorted(citation[\"document_ids\"]):\n", - " if document_id not in document_id_to_number:\n", - " citation_number += 1 # Increment for a new document_id\n", - " document_id_to_number[document_id] = citation_number\n", - " citation_numbers.append(document_id_to_number[document_id])\n", - "\n", - " # Adjust start/end with offset\n", - " start, end = citation['start'] + offset, citation['end'] + offset\n", - " placeholder = ''.join([f'[{number}]' for number in citation_numbers])\n", - " # Bold the cited text and append the placeholder\n", - " modification = f'**{text[start:end]}**{placeholder}'\n", - " # Replace the cited text with its bolded version + placeholder\n", - " text = text[:start] + modification + text[end:]\n", - " # Update the offset for subsequent replacements\n", - " offset += len(modification) - (end - start)\n", - "\n", - " # Prepare citations for listing at the bottom, ensuring unique document_ids are listed once\n", - " unique_citations = {number: doc_id for doc_id, number in document_id_to_number.items()}\n", - " citation_list = '\\n'.join([f'[{doc_id}] source: {tool_results[doc_id - 1][\"outputs\"]} \\n based on tool call: {dict(tool_results[doc_id - 1][\"call\"])}' for doc_id, number in sorted(unique_citations.items(), key=lambda item: item[1])])\n", - " text_with_citations = f'{text}\\n\\n{citation_list}'\n", - "\n", - " return text_with_citations\n", - "\n", - "\n", - "print(insert_citations_in_order(response.text, response.citations))\n" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "= running tool query_daily_sales_report, with parameters: {'day': '2023-09-29'}\n", + "== tool results: [{'date': '2023-09-29', 'summary': 'Total Sales Amount: 10000, Total Units Sold: 250'}]\n", + "= running tool query_product_catalog, with parameters: {'category': 'Electronics'}\n", + "== tool results: [{'category': 'Electronics', 'products': [{'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20}, {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15}, {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25}]}]\n", + "Tool results that will be fed back to the model in step 4:\n", + "[\n", + " {\n", + " \"call\": {\n", + " \"name\": \"query_daily_sales_report\",\n", + " \"parameters\": {\n", + " \"day\": \"2023-09-29\"\n", + " },\n", + " \"generation_id\": \"eaf955e3-623d-4796-bf51-23b07c66ed2c\"\n", + " },\n", + " \"outputs\": [\n", + " {\n", + " \"date\": \"2023-09-29\",\n", + " \"summary\": \"Total Sales Amount: 10000, Total Units Sold: 250\"\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"call\": {\n", + " \"name\": \"query_product_catalog\",\n", + " \"parameters\": {\n", + " \"category\": \"Electronics\"\n", + " },\n", + " \"generation_id\": \"eaf955e3-623d-4796-bf51-23b07c66ed2c\"\n", + " },\n", + " \"outputs\": [\n", + " {\n", + " \"category\": \"Electronics\",\n", + " \"products\": [\n", + " {\n", + " \"product_id\": \"E1001\",\n", + " \"name\": \"Smartphone\",\n", + " \"price\": 500,\n", + " \"stock_level\": 20\n", + " },\n", + " {\n", + " \"product_id\": \"E1002\",\n", + " \"name\": \"Laptop\",\n", + " \"price\": 1000,\n", + " \"stock_level\": 15\n", + " },\n", + " {\n", + " \"product_id\": \"E1003\",\n", + " \"name\": \"Tablet\",\n", + " \"price\": 300,\n", + " \"stock_level\": 25\n", + " }\n", + " ]\n", + " }\n", + " ]\n", + " }\n", + "]\n" + ] + } + ], + "source": [ + "tool_results = []\n", + "# Iterate over the tool calls generated by the model\n", + "for tool_call in response.tool_calls:\n", + " # here is where you would call the tool recommended by the model, using the parameters recommended by the model\n", + " print(f\"= running tool {tool_call.name}, with parameters: {tool_call.parameters}\")\n", + " output = functions_map[tool_call.name](**tool_call.parameters)\n", + " # store the output in a list\n", + " outputs = [output]\n", + " print(f\"== tool results: {outputs}\")\n", + " # store your tool results in this format\n", + " tool_results.append({\n", + " \"call\": tool_call,\n", + " \"outputs\": outputs\n", + " })\n", + "\n", + "print(\"Tool results that will be fed back to the model in step 4:\")\n", + "print(json.dumps(tool_results, indent=4))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8cKlLk18tLGr" + }, + "source": [ + "## Step 4 - The model generates a final answer based on the tool results\n", + "Finally, the developer calls the Cohere model, providing the tools results, in order to generate the model's final answer. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "MKnjXVfXtLGr" + }, + "outputs": [], + "source": [ + "response = co.chat(\n", + " message=message,\n", + " tools=tools,\n", + " tool_results=tool_results,\n", + " preamble=preamble,\n", + " model=\"command-r\",\n", + " temperature=0.3\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "jlxKTsaztLGr", + "outputId": "b2cd8667-bca9-4928-c423-61930b4b49fa" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "RwH2O3FptLGr" - }, - "source": [ - "Yiha. You've used Cohere for Tool Use. Tool use opens up a wide range of new use cases. Here are a few examples:\n", - "\n", - "- **Function calling**: It's now possible to ask the model to output a JSON object with specific function parameters.\n", - "For instance, this allows your chatbot to interact with your CRM to change the status of a deal, or to engage with a Python interpreter to conduct data science analyses.\n", - "\n", - "- **Query transformation**: You can transform a user message into a search query for a vector database or any search engine.\n", - "For instance, this enables your work assistant to automatically retrieve the appropriate data from your company's documentation by creating the right query for your vector database.\n", - "\n", - "- **Advanced searches**: You can transform a user message into one-or-many queries, to do multiple subtasks based on the content of the message.\n", - "For instance, this allows your chatbot to search across different databases and platforms to retrieve relevant information or to conduct comparative analysis.\n", - "\n" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Final answer:\n", + "On the 29th of September 2023, there were 10,000 sales with 250 units sold. \n", + "\n", + "The Electronics category contains three products. There are details below:\n", + "\n", + "| Product Name | Price | Stock Level |\n", + "| ------------ | ----- | ----------- |\n", + "| Smartphone | 500 | 20 |\n", + "| Laptop | 1000 | 15 |\n", + "| Tablet | 300 | 25 | \n", + "\n", + "The total stock level for Electronics items is 50.\n" + ] + } + ], + "source": [ + "print(\"Final answer:\")\n", + "print(response.text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "niMkAr2PN9j4" + }, + "source": [ + "## Bonus: Citations come for free with Cohere! 🎉\n", + "\n", + "At Cohere, model generations come with... precise citations! 🎉\n", + "The model cites which groups of words, in the tool results, were used to generate the final answer. \n", + "These citations make it easy to check where the model’s generated response claims are coming from. \n", + "They help users gain visibility into the model reasoning, and sanity check the final model generation. \n", + "These citations are optional — you can decide to ignore them." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "9wuoCUBwtLGr", + "outputId": "da3c0dc5-6b87-42ea-d64b-e7e85c40273e" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "FXOSzfqRCLBH" - }, - "outputs": [], - "source": [] + "name": "stdout", + "output_type": "stream", + "text": [ + "Citations that support the final answer:\n", + "{'start': 7, 'end': 29, 'text': '29th of September 2023', 'document_ids': ['query_daily_sales_report:0:0']}\n", + "{'start': 42, 'end': 75, 'text': '10,000 sales with 250 units sold.', 'document_ids': ['query_daily_sales_report:0:0']}\n", + "{'start': 112, 'end': 127, 'text': 'three products.', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 234, 'end': 244, 'text': 'Smartphone', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 247, 'end': 250, 'text': '500', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 253, 'end': 255, 'text': '20', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 260, 'end': 266, 'text': 'Laptop', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 269, 'end': 273, 'text': '1000', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 276, 'end': 278, 'text': '15', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 283, 'end': 289, 'text': 'Tablet', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 292, 'end': 295, 'text': '300', 'document_ids': ['query_product_catalog:1:0']}\n", + "{'start': 298, 'end': 300, 'text': '25', 'document_ids': ['query_product_catalog:1:0']}\n" + ] } - ], - "metadata": { + ], + "source": [ + "print(\"Citations that support the final answer:\")\n", + "for cite in response.citations:\n", + " print(cite)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "provenance": [] + "base_uri": "https://localhost:8080/" }, - "kernelspec": { - "display_name": "hackathon_demo", - "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" + "id": "7td1J80DOKTM", + "outputId": "e6e4fa7d-67eb-42ca-e736-9a45a47a6c1d" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "On the **29th of September 2023**[1], there were **10,000 sales with 250 units sold.**[1] \n", + "\n", + "The Electronics category contains **three products.**[2] There are details below:\n", + "\n", + "| Product Name | Price | Stock Level |\n", + "| ------------ | ----- | ----------- |\n", + "| **Smartphone**[2] | **500**[2] | **20**[2] |\n", + "| **Laptop**[2] | **1000**[2] | **15**[2] |\n", + "| **Tablet**[2] | **300**[2] | **25**[2] | \n", + "\n", + "The total stock level for Electronics items is 50.\n", + "\n", + "[1] source: [{'date': '2023-09-29', 'summary': 'Total Sales Amount: 10000, Total Units Sold: 250'}] \n", + " based on tool call: {'name': 'query_daily_sales_report', 'parameters': {'day': '2023-09-29'}, 'generation_id': 'eaf955e3-623d-4796-bf51-23b07c66ed2c'}\n", + "[2] source: [{'category': 'Electronics', 'products': [{'product_id': 'E1001', 'name': 'Smartphone', 'price': 500, 'stock_level': 20}, {'product_id': 'E1002', 'name': 'Laptop', 'price': 1000, 'stock_level': 15}, {'product_id': 'E1003', 'name': 'Tablet', 'price': 300, 'stock_level': 25}]}] \n", + " based on tool call: {'name': 'query_product_catalog', 'parameters': {'category': 'Electronics'}, 'generation_id': 'eaf955e3-623d-4796-bf51-23b07c66ed2c'}\n" + ] } + ], + "source": [ + "def insert_citations_in_order(text, citations):\n", + " \"\"\"\n", + " A helper function to pretty print citations.\n", + " \"\"\"\n", + " offset = 0\n", + " document_id_to_number = {}\n", + " citation_number = 0\n", + " modified_citations = []\n", + "\n", + " # Process citations, assigning numbers based on unique document_ids\n", + " for citation in citations:\n", + " citation_numbers = []\n", + " for document_id in sorted(citation[\"document_ids\"]):\n", + " if document_id not in document_id_to_number:\n", + " citation_number += 1 # Increment for a new document_id\n", + " document_id_to_number[document_id] = citation_number\n", + " citation_numbers.append(document_id_to_number[document_id])\n", + "\n", + " # Adjust start/end with offset\n", + " start, end = citation['start'] + offset, citation['end'] + offset\n", + " placeholder = ''.join([f'[{number}]' for number in citation_numbers])\n", + " # Bold the cited text and append the placeholder\n", + " modification = f'**{text[start:end]}**{placeholder}'\n", + " # Replace the cited text with its bolded version + placeholder\n", + " text = text[:start] + modification + text[end:]\n", + " # Update the offset for subsequent replacements\n", + " offset += len(modification) - (end - start)\n", + "\n", + " # Prepare citations for listing at the bottom, ensuring unique document_ids are listed once\n", + " unique_citations = {number: doc_id for doc_id, number in document_id_to_number.items()}\n", + " citation_list = '\\n'.join([f'[{doc_id}] source: {tool_results[doc_id - 1][\"outputs\"]} \\n based on tool call: {dict(tool_results[doc_id - 1][\"call\"])}' for doc_id, number in sorted(unique_citations.items(), key=lambda item: item[1])])\n", + " text_with_citations = f'{text}\\n\\n{citation_list}'\n", + "\n", + " return text_with_citations\n", + "\n", + "\n", + "print(insert_citations_in_order(response.text, response.citations))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RwH2O3FptLGr" + }, + "source": [ + "Now, you've used Cohere for Tool Use. Tool use opens up a wide range of new use cases. Here are a few examples:\n", + "\n", + "- **Function calling**: It's now possible to ask the model to output a JSON object with specific function parameters.\n", + "For instance, this allows your chatbot to interact with your CRM to change the status of a deal, or to engage with a Python interpreter to conduct data science analyses.\n", + "\n", + "- **Query transformation**: You can transform a user message into a search query for a vector database or any search engine.\n", + "For instance, this enables your work assistant to automatically retrieve the appropriate data from your company's documentation by creating the right query for your vector database.\n", + "\n", + "- **Advanced searches**: You can transform a user message into one-or-many queries, to do multiple subtasks based on the content of the message.\n", + "For instance, this allows your chatbot to search across different databases and platforms to retrieve relevant information or to conduct comparative analysis.\n", + "\n" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/agents/agent_memory_walkthrough.ipynb b/notebooks/agents/agent_memory_walkthrough.ipynb index cbb0a524..b0717cf0 100644 --- a/notebooks/agents/agent_memory_walkthrough.ipynb +++ b/notebooks/agents/agent_memory_walkthrough.ipynb @@ -1,19 +1,9 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "# Notebook Overview\n", @@ -23,9 +13,9 @@ "The way we make LLMs aware of previous information is by simply providing them the full conversation history, i.e., the concatenation of previous input queries and generations.\n", "\n", "As Agents become more and more used, we face the issue to make Agents fully aware of the info from previous turns.\n", - "The current approach is to pass the Agent the generations of the previous turns (see https://python.langchain.com/docs/modules/agents/how_to/custom_agent/), i.e., to do the same thing we do with LLMs. However, as we show below, while this is a good approach for LLMs, it is not for Agents. The reason is that, given the same input, LLMs *only* produce the final generation; conversely, Agents *first* produce a reasoning chain (intermediate steps), *then* produce the final outcome. Hence, if we only retain the final generation, we are loosing some crucial info: the reasoning chain.\n", + "The current approach is to pass the Agent the generations of the previous turns (see https://python.langchain.com/docs/modules/agents/how_to/custom_agent/). However, as we show below, while this is a good approach for LLMs it is not for Agents. Given the same input, LLMs *only* produce the final generation; conversely, Agents *first* produce a reasoning chain (intermediate steps), *then* produce the final outcome. Hence, if we only retain the final generation we lose some crucial info: the reasoning chain.\n", "\n", - "A straightforward solution to this issue would be to append to the conversation history from both the reasoning chain and the generations. This is problematic due to the fact that reasoning chains can be very long, especially when the model makes mistakes, and corrects itself. Using the full reasoning chains would (i) introduce a lot of noise; (ii) quickly fill the whole input window of the model.\n", + "A straightforward solution to this issue would be to append to the conversation history from both the reasoning chain and the generations. This is problematic due to the fact that reasoning chains can be very long, especially when the model makes mistakes and corrects itself. Using the full reasoning chains would (i) introduce a lot of noise; (ii) quickly fill the whole input window of the model.\n", "\n", "## Objective\n", "\n", @@ -45,33 +35,23 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 1: Setup the Prompt and the Agent" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "is_executing": true }, "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "\n", "# !pip install cohere\n", "# !pip install python-dotenv\n", "# !pip install pandas" @@ -81,10 +61,7 @@ "cell_type": "code", "execution_count": 17, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -107,10 +84,7 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -122,10 +96,7 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -137,10 +108,7 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -152,10 +120,7 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -179,10 +144,7 @@ "cell_type": "code", "execution_count": 18, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -205,13 +167,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 2: Conversation without memory\n" ] }, @@ -219,10 +178,7 @@ "cell_type": "code", "execution_count": 10, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -231,12 +187,12 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will use python to read the CSV file and extract the column names.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\n\\ndf = pd.read_csv('revenue_table.csv')\\n\\nprint(df.columns)\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3mIndex(['Unnamed: 0', 'time', 'revenue', 'loss'], dtype='object')\n", - "\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3mIndex(['Unnamed: 0', 'time', 'revenue', 'loss'], dtype='object')\n", + "\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: The column names in the CSV file are:\n", "- Unnamed: 0\n", @@ -247,9 +203,9 @@ "- Unnamed: 0\n", "- time\n", "- revenue\n", - "- loss\u001b[0m\n", + "- loss\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -265,10 +221,7 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -277,8 +230,8 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3mPlan: I will ask the user for clarification on what data they would like to visualise.\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3mPlan: I will ask the user for clarification on what data they would like to visualise.\n", "Action: ```json\n", "[\n", " {\n", @@ -290,9 +243,9 @@ "Relevant Documents: None\n", "Cited Documents: None\n", "Answer: Hello, could you please clarify what data you would like to see plotted?\n", - "Grounded answer: Hello, could you please clarify what data you would like to see plotted?\u001b[0m\n", + "Grounded answer: Hello, could you please clarify what data you would like to see plotted?\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -307,10 +260,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "Without memory, the model cannot answer follow up questions because it misses the necessary previous context" @@ -319,13 +269,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 3. Conversation with Memory using AI Messages\n", "\n", "Here we will populate the chat history only with the generations from the model. This is the current approach used, e.g., here: https://python.langchain.com/docs/modules/agents/how_to/custom_agent/" @@ -335,10 +282,7 @@ "cell_type": "code", "execution_count": 88, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -347,23 +291,23 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will copy and paste the code from the previous conversation and add code to plot the revenue numbers.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\ndata = pd.read_csv('data/sample.csv')\\n\\n# Plot revenue numbers\\nplt.plot(data['revenue'])\\n\\nplt.savefig('revenue_plot.png')\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3mFileNotFoundError(2, 'No such file or directory')\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "\u001B[0m\u001B[36;1m\u001B[1;3mFileNotFoundError(2, 'No such file or directory')\u001B[0m\u001B[32;1m\u001B[1;3m\n", "The code is throwing an error because the file doesn't exist in the specified location. I will amend the file path and re-run the code.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\ndata = pd.read_csv('sample.csv')\\n\\n# Plot revenue numbers\\nplt.plot(data['revenue'])\\n\\nplt.savefig('revenue_plot.png')\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3mFileNotFoundError(2, 'No such file or directory')\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "\u001B[0m\u001B[36;1m\u001B[1;3mFileNotFoundError(2, 'No such file or directory')\u001B[0m\u001B[32;1m\u001B[1;3m\n", "The file path is still incorrect. I will amend it and re-run the code.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\ndata = pd.read_csv('../data/sample.csv')\\n\\n# Plot revenue numbers\\nplt.plot(data['revenue'])\\n\\nplt.savefig('revenue_plot.png')\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3mFileNotFoundError(2, 'No such file or directory')\u001b[0m\u001b[32;1m\u001b[1;3mReflection: The file path is still incorrect. I will ask the user to provide the correct file path.\n", + "\u001B[0m\u001B[36;1m\u001B[1;3mFileNotFoundError(2, 'No such file or directory')\u001B[0m\u001B[32;1m\u001B[1;3mReflection: The file path is still incorrect. I will ask the user to provide the correct file path.\n", "Relevant Documents: 0,1,2\n", "Cited Documents: 0,1,2\n", "Answer: The file path provided is incorrect. Please provide the correct file path so that I can plot the revenue numbers. I have tried '../data/sample.csv' but this also doesn't work.\n", - "Grounded answer: The file path provided is incorrect. Please provide the correct file path so that I can plot the revenue numbers. I have tried '../data/sample.csv' but this also doesn't work.\u001b[0m\n", + "Grounded answer: The file path provided is incorrect. Please provide the correct file path so that I can plot the revenue numbers. I have tried '../data/sample.csv' but this also doesn't work.\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -378,25 +322,19 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "Also in this case, the model cannot manage the follow up question. The reason is that the AI message tells is only part of the necessary context: we need more info from previous turns.\n" + "Also in this case, the model cannot manage the follow up question. The reason is that the AI message only tells part of the necessary context: we need more info from previous turns.\n" ] }, { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 4: Conversation with Memory using AI Messages and Human Messages" ] }, @@ -404,10 +342,7 @@ "cell_type": "code", "execution_count": 14, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -416,18 +351,18 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will copy and paste the code from the previous conversation into this one, and then use it to plot the revenue numbers.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\ndata = pd.read_csv('modified_revenue_table.csv')\\n\\n# Plot the revenue numbers\\nplt.plot(data['revenue'])\\n\\nplt.savefig('revenue_plot.png')\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: Here's a plot of the revenue numbers:\n", "![Revenue plot](\"revenue_plot.png\")\n", "Grounded answer: Here's a plot of the revenue numbers:\n", - "! [Revenue plot](\"revenue_plot.png\")\u001b[0m\n", + "! [Revenue plot](\"revenue_plot.png\")\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] }, { @@ -454,23 +389,17 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "It works! let's go on with the conversation." + "It works! Let's go on with the conversation." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -479,18 +408,18 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will copy and paste the previous code and make the changes requested by the user. Then I will execute the code to plot the graph with the changes applied.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': 'import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\n# Read the CSV file into a DataFrame\\ndf = pd.read_csv(\"modified_revenue_table.csv\")\\n\\n# Plot revenue against time\\nplt.plot(df[\"time\"], df[\"revenue\"], marker=\"o\")\\n\\n# Set minimum and maximum values for y-axis\\nplt.ylim(0, 1000)\\n\\nplt.savefig(\"revenue_plot.png\")'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: Here's the plot with the requested changes:\n", "![Revenue plot](\"revenue_plot.png\")\n", "Grounded answer: Here's the plot with the requested changes:\n", - "! [Revenue plot](\"revenue_plot.png\")\u001b[0m\n", + "! [Revenue plot](\"revenue_plot.png\")\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] }, { @@ -520,30 +449,24 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "The model does what we asked, but it decides to introduce the marker=\"o\" in the plotting function. While in this case the modification of the code does not affect the quality of the output, this is still an undesidered behaviour, since the model is introducing a modification that was not required.\n", "\n", - "To address this problem, we can further enrich the chat history, by adding information from the reasoning chain\n" + "To address this problem, we can further enrich the chat history by adding information from the reasoning chain.\n" ] }, { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 5: Conversation with Memory using AI Messages, Human Messages and the Reasoning Chain\n", "\n", - "To enrich the chat history, we will include in it also the resoning chains produced by the model. Such chains can be very long, especially in those cases in which errors are made, and the agent needs several attempts to get to the final output. Hence, by concatenating all the reasoning chains, we might have two issues: (i) noisy information; (ii) we would quickly hit max input length.\n", + "Reasoning chains can be very long, especially in the cases that contain errors and the agent needs several attempts to get to the final output. Hence, by concatenating all the reasoning chains, we might have two issues: (i) noisy information; (ii) we would quickly hit max input length.\n", "\n", "To avoid this issue, we need a way to extract the relevant info from the previous turns. Below, we propose a simple approach to info extraction. We format the extracted info in such a way to enhance human interpretability. We call the objects passed in the chat history *augmented memory objects*." ] @@ -552,10 +475,7 @@ "cell_type": "code", "execution_count": 14, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -586,10 +506,7 @@ "cell_type": "code", "execution_count": 91, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -600,10 +517,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "Below, an example of the augmented memory object generated by the model. You can see that the agent now has full visibility on what it did in the previous step." @@ -613,10 +527,7 @@ "cell_type": "code", "execution_count": 92, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -650,10 +561,7 @@ "cell_type": "code", "execution_count": 87, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -662,20 +570,20 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will copy and paste the previous code, and modify the y axis limits as requested.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\ndata = pd.read_csv('modified_revenue_table.csv')\\n\\n# Plot the revenue numbers\\nplt.plot(data['revenue'])\\n\\n# Set y axis limits\\nplt.ylim(0, 1000)\\n\\nplt.savefig('revenue_plot.png')\"}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: Here's the plot with the requested y axis limits:\n", "\n", "![Revenue plot](\"revenue_plot.png\")\n", "Grounded answer: Here's the plot with the requested y axis limits:\n", "\n", - "! [Revenue plot](\"revenue_plot.png\")\u001b[0m\n", + "! [Revenue plot](\"revenue_plot.png\")\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] }, { @@ -702,10 +610,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "We can see that, now, the plot only includes the modification we asked for, and nothing else. This is possible because we are now providing the Agent with the code it previously generated, and the Agent re-uses that code, making only the necessary modifications. This is fundamentally different from what we observed before, when the Agent had to re-create from scratch the code.\n", @@ -714,18 +619,6 @@ "\n", "In a future post, we will explore how to handle really long historical context using vector databases." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/notebooks/agents/agentic-RAG/agentic_rag_langchain.ipynb b/notebooks/agents/agentic-RAG/agentic_rag_langchain.ipynb index cdefbbaa..de23b8a7 100644 --- a/notebooks/agents/agentic-RAG/agentic_rag_langchain.ipynb +++ b/notebooks/agents/agentic-RAG/agentic_rag_langchain.ipynb @@ -1,12 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -14,21 +7,23 @@ "# Notebook Overview\n", "\n", "## Motivation\n", - "Asking questions over documents continues to be an important retrieval augmented generation (RAG) task. However, the document complexity can significantly influence overall RAG performance, particularly when the documents are PDFs that contain a mix of text and tables. Finding an optimal strategy to parse this information, chunk, embed and retrieve it is thus quite critical to obtaining accurate results. Furthermore, if the questions being asked over the retrieved documents require mathematical reasoning, then having a model that can validate those operations is quite useful.\n", + "Retrieval-augmented generation (RAG) allows language models to generate grounded answers to questions about documents. However, the complexity of the documents can significantly influence overall RAG performance. For instance, the documents may be PDFs that contain a mix of text and tables. \n", + "\n", + "More broadly, the implementation of a RAG pipeline - including parsing and chunking of documents, along with the embedding and retrieval of the chunks - is critical to the accuracy of grounded answers. Additionally, it is sometimes not sufficient to merely retrieve the answers; a user may want further postprocessing performed on the output. This use case would benefit from giving the model access to tools.\n", "\n", "## Objective\n", - "In this notebook we will guide you through the best practices of setting up a RAG pipeline to process documents that contain both tables and text. In addition, we will show you how to create a Cohere ReAct agent with access to a RAG pipeline tool to improve accuracy. The general structure of the nb is as follows:\n", + "In this notebook, we will guide you through best practices for setting up a RAG pipeline to process documents that contain both tables and text. We will also demonstrate how to create a [ReAct](https://python.langchain.com/v0.1/docs/modules/agents/agent_types/react/) agent with a Cohere model, and then give the agent access to a RAG pipeline tool to improve accuracy. The general structure of the notebook is as follows:\n", "\n", - "1. individual components around parsing, retrieval and generation are covered for documents with mixed tabular and textual data\n", - "2. a class object is created that can be used to instantiate the pipeline with parametric input\n", - "3. the RAG pipeline is then used as a tool for a cohere react agent\n", + "- individual components around parsing, retrieval and generation are covered for documents with mixed tabular and textual data\n", + "- a class object is created that can be used to instantiate the pipeline with parametric input\n", + "- the RAG pipeline is then used as a tool for a Cohere ReACT agent\n", "\n", "# Reference Documents\n", - "we recommend the following as a guide on doing [semi-structured RAG](https://github.com/langchain-ai/langchain/blob/master/cookbook/Semi_Structured_RAG.ipynb)\n", + "We recommend the following notebook as a guide to [semi-structured RAG](https://github.com/langchain-ai/langchain/blob/master/cookbook/Semi_Structured_RAG.ipynb).\n", "\n", - "we recommend this notebook to explore various parsing techniques for [PDFs](https://github.com/cohere-ai/notebooks/blob/main/notebooks/guides/Document_Parsing_For_Enterprises.ipynb)\n", + "We also recommend the following notebook to explore various parsing techniques for [PDFs](https://github.com/cohere-ai/notebooks/blob/main/notebooks/guides/Document_Parsing_For_Enterprises.ipynb).\n", "\n", - "various langchain supported [parsers](https://python.langchain.com/docs/modules/data_connection/document_loaders/pdf/)\n", + "Various LangChain-supported parsers can be found [here](https://python.langchain.com/docs/modules/data_connection/document_loaders/pdf/).\n", "\n", "## Table of Contents\n", "- Section 1\n", @@ -101,7 +96,6 @@ "from datasets import load_dataset\n", "from joblib import Parallel, delayed\n", "\n", - "\n", "os.environ['COHERE_API_KEY'] = \"\"" ] }, @@ -109,13 +103,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "\n", "# Parsing\n", "\n", "To improve RAG performance on PDFs with mixed types (text and tables), we investigated a number of parsing and chunking strategies from various libraries:\n", - "- PyPDFLoader (LC)\n", - "- LlamaParse (Llama-Index)\n", - "- Unstructured IO\n", + "- [PyPDFLoader (LC)](https://api.python.langchain.com/en/latest/document_loaders/langchain_community.document_loaders.pdf.PyPDFLoader.html)\n", + "- [LlamaParse](https://docs.llamaindex.ai/en/stable/llama_cloud/llama_parse/) (Llama-Index)\n", + "- [Unstructured](https://unstructured.io/)\n", "\n", "\n", "We have found that the best option for parsing is unstructured.io since the parser can:\n", @@ -125,22 +119,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "id": "eqcorKP4YEH6" }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "This function will be deprecated in a future release and `unstructured` will simply use the DEFAULT_MODEL from `unstructured_inference.model.base` to set default model name\n", - "Some weights of the model checkpoint at microsoft/table-transformer-structure-recognition were not used when initializing TableTransformerForObjectDetection: ['model.backbone.conv_encoder.model.layer4.0.downsample.1.num_batches_tracked', 'model.backbone.conv_encoder.model.layer3.0.downsample.1.num_batches_tracked', 'model.backbone.conv_encoder.model.layer2.0.downsample.1.num_batches_tracked']\n", - "- This IS expected if you are initializing TableTransformerForObjectDetection from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n", - "- This IS NOT expected if you are initializing TableTransformerForObjectDetection from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n" - ] - } - ], + "outputs": [], "source": [ "# UNSTRUCTURED pdf loader\n", "# Get elements\n", @@ -204,15 +187,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "\n", "# Vector Store Setup\n", "\n", - "There are many options to setup a vector store. Here we show how to set one up using Chroma and Langchains Multi-vector retrieval.\n", - "We use multi-vector retrieval because oftentimes a summary may be able to distill more accurately what a chunk is about, leading to better retrieval.\n", + "There are many options for setting up a vector store. Here, we show how to do so using [Chroma](https://www.trychroma.com/) and Langchain's Multi-vector retrieval.\n", + "As the name implies, multi-vector retrieval allows us to store multiple vectors per document; for instance, for a single document chunk, one could keep embeddings for both the chunk itself, and a summary of that document. A summary may be able to distill more accurately what a chunk is about, leading to better retrieval.\n", "\n", "You can read more about this here: https://python.langchain.com/docs/modules/data_connection/retrievers/multi_vector/\n", "\n", - "The process is as follows:\n", + "Below, we demonstrate the following process:\n", "- summaries of each chunk are embedded\n", "- during inference, the multi-vector retrieval returns the full context document related to the summary" ] @@ -223,9 +206,7 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "co = cohere.Client()\n", - "\n", "def get_chat_output(message, preamble, chat_history, model, temp, documents=None):\n", " return co.chat(\n", " message=message,\n", @@ -260,7 +241,6 @@ "outputs": [], "source": [ "# generate table and text summaries\n", - "\n", "prompt_text = \"\"\"You are an assistant tasked with summarizing tables and text. \\ \n", "Give a concise summary of the table or text. Table or text chunk: {element}. Only provide the summary and no other text.\"\"\"\n", "\n", @@ -311,7 +291,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "\n", "# RAG Pipeline" ] }, @@ -319,11 +299,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "the query process can be broken down into the following steps:\n", + "With our database in place, we can run queries against it. The query process can be broken down into the following steps:\n", "\n", - "1. augment the query, this really helps retrieve all the relevant information\n", - "2. use each augmented query to retrieve the top k docs and then rerank them\n", - "3. concatenate all the shortlisted/reranked docs and pass them to the generation model" + "- augment the query, this really helps retrieve all the relevant information\n", + "- use each augmented query to retrieve the top k docs and then rerank them\n", + "- concatenate all the shortlisted/reranked docs and pass them to the generation model" ] }, { @@ -382,6 +362,13 @@ "## Example " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now test out a query. In this example, the final answer can be found on page 12 of the PDF, which aligns with the response provided by the model:" + ] + }, { "cell_type": "code", "execution_count": 10, @@ -413,25 +400,18 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "the final answer is correct based on page 12 in the PDF and we can see that the information retrieved is linked to that table :) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### chat history management" + "### Chat History Management" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "an example of asking a follow up question that relies on the chat history but does not require a re-run of RAG.\n", + "In the example below, we ask a follow up question that relies on the chat history, but does not require a rerun of the RAG pipeline.\n", "\n", - "The search_queries_only flag can be used to determine whether RAG needs to be rerun or not i.e. it can help easily identify if the query passed needs retrieval.\n", + "We detect questions that do not require RAG by examining the `search_queries` object returned by calling `co.chat` to generate candidate queries to answer our question. If this object is empty, then the model has determined that a document query is not needed to answer the question.\n", "\n", - "In the example below, the else statement is invoked based on query2. In the else we pass in history without documents as the new query does not need to call the RAG pipeline " + "In the example below, the `else` statement is invoked based on `query2`. We still pass in the chat history, allowing the question to be answered with only the prior context." ] }, { @@ -480,10 +460,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "\n", "# RAG Pipeline Class\n", "\n", - "Here we connect all the pieces discussed above into one class object that is then used as a tool for a cohere react agent. This class is to help consolidate and clarify the key parameters used to define the RAG pipeline." + "Here, we connect all of the pieces discussed above into one class object, which is then used as a tool for a Cohere ReAct agent. This class definition consolidates and clarify the key parameters used to define the RAG pipeline." ] }, { @@ -737,15 +717,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "# Cohere REACT Agent with RAG Tool" + "\n", + "# Cohere ReAct Agent with RAG Tool" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "we build a simple agent using the RAG pipeline previously defined. The e2e rag pipeline is provided as a tool in addition to a python tool. The premise in coupling these tools is so that the mathematical steps can be done using a python tool to improve accuracy." + "Finally, we build a simple agent that utilizes the RAG pipeline defined above. We do this by granting the agent access to two tools:\n", + "\n", + "- the end-to-end RAG pipeline \n", + "- a Python interpreter\n", + "\n", + "The intention behind coupling these tools is to enable the model to perform mathematical and other postprocessing operations on RAG outputs using Python." ] }, { @@ -856,18 +841,18 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will search for the charges for services in 2022 and 2023.\n", "{'tool_name': 'vectorsearch', 'parameters': {'query': 'charges for services in 2022 and 2023'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3mThe charges for services in 2022 were $5,266 million and in 2023 were $5,769 million.The final answer is from the documents below:\n", + "\u001B[0m\u001B[36;1m\u001B[1;3mThe charges for services in 2022 were $5,266 million and in 2023 were $5,769 million.The final answer is from the documents below:\n", " \n", - " [{'id': 'doc_0', 'snippet': 'Program and General Revenues FY 2023 FY 2022 FY 2021 Category (in millions) Charges for Services (CS) $5,769 $5,266 $5,669 Operating Grants and Contributions (OGC) 27,935 31,757 28,109 Capital Grants and Contributions (CGC) 657 656 675 Real Estate Taxes (RET) 31,502 29,507 31,421 Sales and Use Taxes (SUT) 10,577 10,106 7,614 Personal Income Taxes (PIT) 15,313 15,520 15,795 Income Taxes, Other (ITO) 13,181 9,521 9,499 Other Taxes* (OT) 3,680 3,777 2,755 Investment Income* (II) 694 151 226 Unrestricted Federal and State Aid (UFSA) 234 549 108 Other* (O) Total Program and General Revenues - Primary Government 2,305 $110,250 $107,535 $104,176 708 725', 'title': 'chunk 0'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + " [{'id': 'doc_0', 'snippet': 'Program and General Revenues FY 2023 FY 2022 FY 2021 Category (in millions) Charges for Services (CS) $5,769 $5,266 $5,669 Operating Grants and Contributions (OGC) 27,935 31,757 28,109 Capital Grants and Contributions (CGC) 657 656 675 Real Estate Taxes (RET) 31,502 29,507 31,421 Sales and Use Taxes (SUT) 10,577 10,106 7,614 Personal Income Taxes (PIT) 15,313 15,520 15,795 Income Taxes, Other (ITO) 13,181 9,521 9,499 Other Taxes* (OT) 3,680 3,777 2,755 Investment Income* (II) 694 151 226 Unrestricted Federal and State Aid (UFSA) 234 549 108 Other* (O) Total Program and General Revenues - Primary Government 2,305 $110,250 $107,535 $104,176 708 725', 'title': 'chunk 0'}]\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: The charges for services in 2022 were $5,266 million and in 2023 were $5,769 million.\n", - "Grounded answer: The charges for services in 2022 were $5,266 million and in 2023 were $5,769 million.\u001b[0m\n", + "Grounded answer: The charges for services in 2022 were $5,266 million and in 2023 were $5,769 million.\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -879,7 +864,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Example of how to handle history with the langchain agent" + "Just like earlier, we can also pass chat history to the LangChain agent to refer to for any other queries." ] }, { @@ -914,7 +899,7 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n" + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n" ] }, { @@ -928,16 +913,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will use the Python Interpreter tool to calculate the mean of the two values.\n", "{'tool_name': 'python_interpreter', 'parameters': {'code': 'import numpy as np\\n\\n# Data\\nvalues = [5266, 5769]\\n\\n# Calculate the mean\\nmean_value = np.mean(values)\\n\\nprint(f\"The mean of the two values is: {mean_value:.0f} million\")'}}\n", - "\u001b[0m\u001b[33;1m\u001b[1;3mThe mean of the two values is: 5518 million\n", - "\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[33;1m\u001B[1;3mThe mean of the two values is: 5518 million\n", + "\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: The mean of the two values is 5518 million.\n", - "Grounded answer: The mean of the two values is 5518 million.\u001b[0m\n", + "Grounded answer: The mean of the two values is 5518 million.\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] }, { @@ -963,11 +948,14 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "source": [ + "# Conclusion\n", + "As you can see, the RAG pipeline can be used as a tool for a Cohere ReAct agent. This allows the agent to access the RAG pipeline for document retrieval and generation, as well as a Python interpreter for postprocessing mathematical operations to improve accuracy. This setup can be used to improve the accuracy of grounded answers to questions about documents that contain both tables and text." + ], + "metadata": { + "collapsed": false + } } ], "metadata": { diff --git a/notebooks/agents/agents_with_deterministic_functions.ipynb b/notebooks/agents/agents_with_deterministic_functions.ipynb index 6fa7b94d..8564db87 100644 --- a/notebooks/agents/agents_with_deterministic_functions.ipynb +++ b/notebooks/agents/agents_with_deterministic_functions.ipynb @@ -1,19 +1,9 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "# Notebook Overview\n", @@ -33,9 +23,9 @@ "## Solution\n", "In this notebook, we propose a simple but effective solution to the challenge defined above: We create a [Langchain ReAct Agent](https://github.com/langchain-ai/langchain-cohere/blob/main/libs/cohere/langchain_cohere/cohere_agent.py) that has access to a deterministic tool that extracts the alphanumeric patterns in the query, and returns a dictionary in which the keys are the parameters, and the values the extracted patterns. The output of the tool is then used to generate the final request.\n", "\n", - "Using such a tool is just one of the possibilities that the Agent has to generate the query: As we will see below, when a more semantic understanding of the query is required, we can ignore the tool and leverage the linguistic capabilities of the LLM powering the Agent to generate the final output.\n", + "Using such a tool is just one of the possibilities that the Agent has to generate the query. As we will see below, when a more semantic understanding of the query is required, we can ignore the tool and leverage the linguistic capabilities of the LLM powering the Agent to generate the final output.\n", "\n", - "With this approach, we bring together the best of two worlds: on the one hand, the ability of LLMs to use tool and generate outputs, on the other one, the reliability and efficiency of deterministic functions.\n", + "With this approach, we bring together the best of two worlds: the ability of LLMs to use tools and generate outputs and the reliability and efficiency of deterministic functions.\n", "\n", "## Table of Contents\n", "\n", @@ -49,13 +39,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 1: Setup" ] }, @@ -63,32 +50,21 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "\n", "# !pip install cohere\n", "# !pip install python-dotenv\n", - "# !pip install pandas\n" + "# !pip install pandas" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -108,10 +84,7 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -122,13 +95,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 2: Define the Tool and the Agent\n", "Here we create a tool which implements the deterministic function to extract alphanumeric strings from the user's query and match them to the right parameter." ] @@ -137,17 +107,13 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ "@tool\n", "def regex_extractor(user_query: str) -> dict:\n", " \"\"\"Function which, given the query from the user, returns a dictionary parameter:value.\"\"\"\n", - "\n", " uuid = re.findall(\"\\s([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\", user_query)\n", " nmgs = re.findall(\"(0000[A-Z0-9]{21})\", user_query)\n", " objref = re.findall(\"\\s([A-Z]{5,9}\\d{3,4}[A-Z]{3,8})\", user_query)\n", @@ -159,12 +125,10 @@ " d_filtered = {k: v for k, v in d.items() if v != []}\n", " return d_filtered\n", "\n", - "\n", "class extract_code_v1productssearch(BaseModel):\n", " user_query: str = Field(\n", " description=\"This is the full input query as received from the user. Do not truncate or modify the query in any way.\"\n", " )\n", - "\n", "regex_extractor.name = \"regex_extractor\"\n", "regex_extractor.args_schema = extract_code_v1productssearch\n", "tools=[regex_extractor]" @@ -174,10 +138,7 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -187,44 +148,39 @@ "# - the cases in which the Agent has to produce an output without using the tool\n", "# - some examples to clarify the task\n", "preamble = \"\"\"You are an assistant that given a user's query about, generates a request an API.\n", - " You can use the tool named \"regex_extractor\".\n", - " Pass to the \"regex_extractor\" tool the entire text of the the input query.\n", - " The tool returns a dictionary, in which keys are the name of the codes, and values a list of extracted codes.\n", - " Create a JSON for each of the key-value pairs in the dictionary.\n", + "You can use the tool named \"regex_extractor\".\n", + "Pass to the \"regex_extractor\" tool the entire text of the the input query.\n", + "The tool returns a dictionary, in which keys are the name of the codes, and values a list of extracted codes.\n", + "Create a JSON for each of the key-value pairs in the dictionary.\n", "\n", - " Return a list of JSONs. Make sure each JSON is properly defined. Do not return any other explanation or comment.\n", - " You MUST generate a perfect JSON object: make sure that each string in the lists is included between quotes.\n", + "Return a list of JSONs. Make sure each JSON is properly defined. Do not return any other explanation or comment.\n", + "You MUST generate a perfect JSON object: make sure that each string in the lists is included between quotes.\n", "\n", - " If the request mentions one of the tags listed below, or a related word, create a dictionary in which the key is \"taxonomies\" and the value the list of capitalized tags.\n", - " Tags list: cars, trucks, clothes, sport\n", + "If the request mentions one of the tags listed below, or a related word, create a dictionary in which the key is \"taxonomies\" and the value the list of capitalized tags.\n", + "Tags list: cars, trucks, clothes, sport\n", "\n", "\n", - " Find a list of examples here:\n", - " User question | parameter for the tool | what you should understand\n", - " Look products GLCMS004AGTCAMIS; 0000234GLCMS0100ANORAKCAA, GLCHL000CGUCHALE | Look products GLCMS004AGTCAMIS; 0000234GLCMS0100ANORAKCAA, GLCHL000CGUCHALE | [{\"objref\":[\"GLCMS004AGTCAMIS\",\"GLCHL000CGUCHALE\"]},{\"nmgs\":[\"0000234GLCMS0100ANORAKCAA\"]}]\n", - " Retrieve id 7410e652-639d-402e-984e-8fd7025f0aac 8bb21b93-2ddf-4a63-af63-ddb6b1be49a1, ref GLPNT0005GUJOGGE GLSBR000BGASOBRE, nmg 0000234GLCHL0200ARTINDIUS | Retrieve id 7410e652-639d-402e-984e-8fd7025f0aac 8bb21b93-2ddf-4a63-af63-ddb6b1be49a1, ref GLPNT0005GUJOGGE GLSBR000BGASOBRE, nmg 0000234GLCHL0200ARTINDIUS | [{\"uuid\":[\"7410e652-639d-402e-984e-8fd7025f0aac\",\"8bb21b93-2ddf-4a63-af63-ddb6b1be49a1\"]}, {\"objref\":[\"GLPNT0005GUJOGGE\",\"GLSBR000BGASOBRE\"]},{\"nmgs\":[\"0000234GLCHL0200ARTINDIUS\"]}]\n", - " Look for items of cars and trucks | Look for items of pants and t-shirts | [{'taxonomies': ['CARS', 'TRUCKS']}]\n", - " Search products sport | Search products dress and jumpsuit | [{'taxonomies': ['SPORT']}]\n", - " \"\"\"" + "Find a list of examples here:\n", + "User question | parameter for the tool | what you should understand\n", + "Look products GLCMS004AGTCAMIS; 0000234GLCMS0100ANORAKCAA, GLCHL000CGUCHALE | Look products GLCMS004AGTCAMIS; 0000234GLCMS0100ANORAKCAA, GLCHL000CGUCHALE | [{\"objref\":[\"GLCMS004AGTCAMIS\",\"GLCHL000CGUCHALE\"]},{\"nmgs\":[\"0000234GLCMS0100ANORAKCAA\"]}]\n", + "Retrieve id 7410e652-639d-402e-984e-8fd7025f0aac 8bb21b93-2ddf-4a63-af63-ddb6b1be49a1, ref GLPNT0005GUJOGGE GLSBR000BGASOBRE, nmg 0000234GLCHL0200ARTINDIUS | Retrieve id 7410e652-639d-402e-984e-8fd7025f0aac 8bb21b93-2ddf-4a63-af63-ddb6b1be49a1, ref GLPNT0005GUJOGGE GLSBR000BGASOBRE, nmg 0000234GLCHL0200ARTINDIUS | [{\"uuid\":[\"7410e652-639d-402e-984e-8fd7025f0aac\",\"8bb21b93-2ddf-4a63-af63-ddb6b1be49a1\"]}, {\"objref\":[\"GLPNT0005GUJOGGE\",\"GLSBR000BGASOBRE\"]},{\"nmgs\":[\"0000234GLCHL0200ARTINDIUS\"]}]\n", + "Look for items of cars and trucks | Look for items of pants and t-shirts | [{'taxonomies': ['CARS', 'TRUCKS']}]\n", + "Search products sport | Search products dress and jumpsuit | [{'taxonomies': ['SPORT']}]\n", + "\"\"\"" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ "# Define the prompt\n", "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "\n", "# Define the agent\n", "llm = ChatCohere(model=\"command-r-plus\", temperature=0)\n", - "\n", "# instantiate agent and agent executor\n", "agent = create_cohere_react_agent(\n", " llm=llm,\n", @@ -242,10 +198,7 @@ "cell_type": "code", "execution_count": 7, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -256,19 +209,16 @@ " .replace(\"json\", \"\")\n", " .replace(\"`\", \"\")\n", " .replace(\"`\", \"\")\n", - " )\n" + " )" ] }, { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Step 3: Run the Agent\n", "Let's now test the Agent we just defined!" ] @@ -277,10 +227,7 @@ "cell_type": "code", "execution_count": 8, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -289,11 +236,11 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will use the regex_extractor tool to extract the codes from the user query.\n", "{'tool_name': 'regex_extractor', 'parameters': {'user_query': 'Look for urn:75f2b737-06dd-4399-9206-a6c11b65138e, GLCMS004AGTCAMIS; 0000234GLCMS0100ANORAKCAA, GLCHL000CGUCHALE'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m{'nmgs': ['0000234GLCMS0100ANORAKCAA'], 'objref': ['GLCMS004AGTCAMIS', 'GLCHL000CGUCHALE'], 'urn': ['urn:75f2b737-06dd-4399-9206-a6c11b65138e']}\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m{'nmgs': ['0000234GLCMS0100ANORAKCAA'], 'objref': ['GLCMS004AGTCAMIS', 'GLCHL000CGUCHALE'], 'urn': ['urn:75f2b737-06dd-4399-9206-a6c11b65138e']}\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: ```json\n", "[\n", @@ -312,9 +259,9 @@ "        \"nmgs\": [\"0000234GLCMS0100ANORAKCAA\"]\n", "    }\n", "]\n", - "```\u001b[0m\n", + "```\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -331,10 +278,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "In the reasoning chain above, we can see that the Agent uses the tool we provided it to extract the strings in the query.\n", @@ -345,10 +289,7 @@ "cell_type": "code", "execution_count": 9, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -372,10 +313,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "As mentioned above, the Agent can use the tool when specific alphanumeric patterns have to be extracted from the query; however, it can also generate the output based on its semantic understanding of the query. For example:" @@ -385,10 +323,7 @@ "cell_type": "code", "execution_count": 10, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -397,11 +332,11 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will use the regex_extractor tool to extract the relevant information from the user request.\n", "{'tool_name': 'regex_extractor', 'parameters': {'user_query': 'I need tennis products'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m{}\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m{}\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: None\n", "Cited Documents: None\n", "Answer: ```json\n", "[\n", @@ -420,9 +355,9 @@ " ]\n", " }\n", "]\n", - "```\u001b[0m\n", + "```\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -440,23 +375,17 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "The Agent run the tool to check if any target string was in the query, then it generated the request body based on its understanding." + "The Agent runs the tool to check if any target string was in the query, then it generated the request body based on its understanding." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -477,10 +406,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ "Finally, the two paths to generation - deterministic and semantic - can be applied in parallel by the Agent, as shown below:" @@ -490,10 +416,7 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -502,11 +425,11 @@ "text": [ "\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", + "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", + "\u001B[32;1m\u001B[1;3m\n", "I will use the regex_extractor tool to extract the codes from the user query. Then, I will create a JSON for each of the key-value pairs in the dictionary.\n", "{'tool_name': 'regex_extractor', 'parameters': {'user_query': 'Look for GLBRL0000GACHALE, nmg 0000234GLCZD0000GUREDTOAA and car products'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m{'nmgs': ['0000234GLCZD0000GUREDTOAA'], 'objref': ['GLBRL0000GACHALE']}\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", + "\u001B[0m\u001B[36;1m\u001B[1;3m{'nmgs': ['0000234GLCZD0000GUREDTOAA'], 'objref': ['GLBRL0000GACHALE']}\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: ```json\n", "[\n", @@ -529,9 +452,9 @@ "        \"taxonomies\": [\"CARS\"]\n", "    }\n", "]\n", - "```\u001b[0m\n", + "```\u001B[0m\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" + "\u001B[1m> Finished chain.\u001B[0m\n" ] } ], @@ -550,10 +473,7 @@ "cell_type": "code", "execution_count": 13, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [ { @@ -575,29 +495,14 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "source": [ - "\n", + "\n", "# Conclusions\n", "\n", "In this notebook we showed how Agents can be used to solve a real-world use case, in which the goal is to create API requests based on the user's query. We did it by providing the Agent with a deterministic tool to extract relevant alphanumeric strings in the query, and matching them to the right parameter name. In parallel, the Agent can leverage the semantic understanding of the query provided by the LLM powering it." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/notebooks/agents/financial-csv-agent/financial_csv_publication.ipynb b/notebooks/agents/financial-csv-agent/financial_csv_publication.ipynb index c7ee3fbf..d36ad183 100644 --- a/notebooks/agents/financial-csv-agent/financial_csv_publication.ipynb +++ b/notebooks/agents/financial-csv-agent/financial_csv_publication.ipynb @@ -1,18 +1,12 @@ { "cells": [ - { - "cell_type": "markdown", - "id": "5c0d5271-8d35-4471-b667-265695cbf11a", - "metadata": {}, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "id": "1d71f595-01ef-4c24-99eb-81b01eec048b", "metadata": {}, "source": [ + "# Financial CSV Agent with Langchain\n", + "\n", "# Notebook Overview\n", "\n", "## Motivation\n", @@ -27,7 +21,7 @@ "Having an Agent which is able to correctly compute these and other ratios would be a great help for any analyst in the field of Finance.\n", "\n", "## Objective\n", - "In this notebook we explore how to setup a [Cohere ReAct Agent](https://github.com/langchain-ai/langchain-cohere/blob/main/libs/cohere/langchain_cohere/cohere_agent.py) to answer questions over tables in Apple's SEC10K 2020 form. We show how this can be done with two variants of a langchain python tool, one that requires you to pass the full path of the dataframe and another that requires the dataframe objects to be loaded in memory. While there is no major difference between the two approaches, we present both to show how to manage files that are loaded in memory vs files in storage. \n", + "In this notebook we explore how to setup a [Cohere ReAct Agent](https://github.com/langchain-ai/langchain-cohere/blob/main/libs/cohere/langchain_cohere/cohere_agent.py) to answer questions over tables in Apple's SEC10K 2020 form. We show how this can be done with two variants of a Langchain Python tool, one that requires you to pass the full path of the dataframe and another that requires the dataframe objects to be loaded in memory. While there is no major difference between the two approaches, we present both to show how to manage files that are loaded in memory vs files in storage. \n", "\n", "## Table of Contents\n", "\n", @@ -84,12 +78,7 @@ "metadata": {}, "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "\n", "#!pip install --quiet langchain langchain_cohere langchain_experimental --upgrade\n", "#!pip install sec-api" ] @@ -108,7 +97,7 @@ "# Introduction\n", "\n", "The aim of this notebook is to showcase how Cohere Langchain Agents can be used to answer questions over tabular data.\n", - "This notebook assumes the input is a set of csv files extracted from Apples SEC 10K filings." + "This notebook assumes the input is a set of csv files extracted from Apple's SEC 10K filings." ] }, { @@ -118,7 +107,7 @@ "source": [ "### Data Loading\n", "\n", - "We use the sec-api to download the income statement and balance sheet from the SEC 10K .htm file. Please note that the tables need to be parsed such that the index is numerical as the python code generation struggles to filter based on index. We have processed the tables and provided them for you." + "We use the sec-api to download the income statement and balance sheet from the SEC 10K .htm file. Please note that the tables need to be parsed such that the index is numerical as the python code generation struggles to filter based on index. We have processed the tables and provided them for you. They can be found [here](https://github.com/cohere-ai/notebooks/tree/main/notebooks/agents/financial-csv-agent). " ] }, { @@ -151,10 +140,10 @@ "\n", "In the example below, we show how the python tool can be used to load a dataframe and extract information from it. To do this successfully we need to:\n", "\n", - "1) pass the file name to the preamble so the model knows how to load the dataframe\n", - "2) pass a preview of the dataframe in the preamble so the model knows which columns/rows to query\n", + "* Pass the file name to the preamble so the model knows how to load the dataframe.\n", + "* Pass a preview of the dataframe in the preamble so the model knows which columns/rows to query.\n", "\n", - "First, let's implement the ReAct agent" + "First, let's implement the ReAct agent." ] }, { @@ -179,7 +168,7 @@ "class ToolInput(BaseModel):\n", " code: str = Field(description=\"Python code to execute.\")\n", "python_tool.args_schema = ToolInput\n", - "tools=[python_tool] \n", + "tools=[python_tool]\n", "\n", "# define the prompt template\n", "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", @@ -245,7 +234,7 @@ } }, "source": [ - "Let's now see how the Agent answers to each of the questions" + "Let's now see how the Agent answers each of the questions." ] }, { @@ -383,7 +372,7 @@ } }, "source": [ - "Let's loop again over the same dictionary of questions" + "Let's loop again over the same dictionary of questions." ] }, { @@ -501,7 +490,7 @@ "class ToolInput(BaseModel):\n", " code: str = Field(description=\"Python code to execute.\")\n", "python_tool.args_schema = ToolInput\n", - "tools=[python_tool] \n", + "tools=[python_tool]\n", "\n", "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", "agent = create_cohere_react_agent(\n", @@ -536,7 +525,7 @@ } }, "source": [ - "We now define a new question" + "We now define a new question." ] }, { @@ -566,7 +555,7 @@ } }, "source": [ - "The answer to this question can be obtained only by accessing both the balance sheet and the income statement, as show below:" + "The answer to this question can be obtained only by accessing both the balance sheet and the income statement, as shown below:" ] }, { @@ -609,7 +598,7 @@ } }, "source": [ - "Let's now get the answer from the Agent" + "Let's now get the answer from the Agent." ] }, { @@ -666,19 +655,6 @@ "source": [ "The Agent defined a plan (\"write and execute Python code to find the largest and smallest values in the relevant columns of the dataframes, then calculate the ratio\") and executed it. It made some mistakes when coding, that resulted in NameError errors, but it fixed them and finally got to the correct answer" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "77a3f5ac", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/notebooks/agents/financial-csv-agent/financial_csv_publication_native.ipynb b/notebooks/agents/financial-csv-agent/financial_csv_publication_native.ipynb index 6532a8d0..0c58e05a 100644 --- a/notebooks/agents/financial-csv-agent/financial_csv_publication_native.ipynb +++ b/notebooks/agents/financial-csv-agent/financial_csv_publication_native.ipynb @@ -2,10 +2,10 @@ "cells": [ { "cell_type": "markdown", - "id": "549c3504", + "id": "df17583b", "metadata": {}, "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" + "# Financial CSV Agent with Native Multi-step Cohere API \n" ] }, { @@ -29,7 +29,7 @@ "\n", "## Objective\n", "\n", - "In this notebook we explore how to setup a [Cohere Agent](https://docs.cohere.com/docs/multi-step-tool-use) to answer questions over tables in Apple's SEC10K 2020 form. [financial_csv_publication.ipynb](#TODO) already showed how to use langchain to ask questions about your data. This notebook will demonstrate how you can build the same agent using Cohere's native API with langchain python tool. We will also explore how to make your agent more resilient to errors. \n", + "In this notebook we explore how to setup a [Cohere Agent](https://docs.cohere.com/docs/multi-step-tool-use) to answer questions over tables in Apple's SEC10K 2020 form. [Financial CSV Agent](https://docs.cohere.com/page/csv-agent) already showed how to use Langchain to ask questions about your data. This notebook will demonstrate how you can build the same agent using Cohere's native API with Langchain Python tool. We will also explore how to make your agent more resilient to errors. \n", "\n", "## Table of Contents\n", "\n", @@ -47,7 +47,7 @@ "id": "a9f349f1", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# Setup" ] @@ -85,12 +85,7 @@ "metadata": {}, "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "\n", "# !pip install --quiet langchain langchain_experimental cohere --upgrade" ] }, @@ -455,7 +450,7 @@ "id": "58a1e1ce", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# Define Python Tool \n", "\n", @@ -511,11 +506,11 @@ "id": "e58c2745", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# Create Cohere Agent \n", "\n", - "As [Vanilla_Multi_Step_Tool_Use.ipynb](https://github.com/cohere-ai/notebooks/blob/fbf6c8dad47d7557314e9248a267175c7a6908d8/notebooks/Vanilla_Multi_Step_Tool_Use.ipynb) shows, you have a lot of flexiblity on how you can customize and interact with the cohere agent. Here I am creating a wrapper so that it automatically determines when to stop calling the tools and output final answer. It will run maximum of 15 steps. " + "As [Multi-Step Tool Use](https://docs.cohere.com/page/basic-multi-step) shows, you have a lot of flexiblity on how you can customize and interact with the cohere agent. Here I am creating a wrapper so that it automatically determines when to stop calling the tools and output final answer. It will run maximum of 15 steps. " ] }, { @@ -618,19 +613,19 @@ "id": "d3e42dd8-20d0-4b97-90fd-4a4ce5836c64", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# QnA over Single Table \n", "\n", - "In the example below, we show how the python tool can be used to load a dataframe and extract information from it. To do this successfully we need to:\n", + "In the example below, we show how the Python tool can be used to load a dataframe and extract information from it. To do this successfully we need to:\n", "\n", - "1) pass the file name to the preamble so the model knows how to load the dataframe\n", - "2) pass a preview of the dataframe in the preamble so the model knows which columns/rows to query\n", + "* Pass the file name to the preamble so the model knows how to load the dataframe\n", + "* Pass a preview of the dataframe in the preamble so the model knows which columns/rows to query\n", "\n", "We will ask the following questions given income statement data. \n", - "1. what is the highest value of cost of goods and service?\n", - "2. what is the largest gross profit margin?\n", - "3. what is the minimum ratio of operating income loss divided by non operating income expense? " + "* What is the highest value of cost of goods and service?\n", + "* What is the largest gross profit margin?\n", + "* What is the minimum ratio of operating income loss divided by non operating income expense? " ] }, { @@ -664,8 +659,7 @@ "|---:|-------------:|:----------------------|------------------------------------------------------:|-----------------------------:|--------------:|--------------------------------:|-----------------------------------------:|--------------------:|----------------------:|----------------------------:|----------------------------------------------------------------------------------------------:|--------------------------:|----------------:|------------------------:|--------------------------:|------------------------------------------------:|--------------------------------------------------:|\n", "| 0 | 0 | 2017-10-01-2018-09-29 | 265595000000 | 1.63756e+11 | 101839000000 | 1.4236e+10 | 1.6705e+10 | 3.0941e+10 | 7.0898e+10 | 2.005e+09 | 7.2903e+10 | 1.3372e+10 | 59531000000 | 3 | 2.98 | 1.98215e+10 | 2.00004e+10 |\n", "| 1 | 1 | 2018-09-30-2018-12-29 | 84310000000 | nan | 32031000000 | nan | nan | nan | nan | nan | nan | nan | 19965000000 | 1.05 | 1.05 | nan | nan |\n", - "| 2 | 2 | 2018-09-30-2019-09-28 | 260174000000 | 1.61782e+11 | 98392000000 | 1.6217e+10 | 1.8245e+10 | 3.4462e+10 | 6.393e+10 | 1.807e+09 | 6.5737e+10 | 1.0481e+10 | 55256000000 | 2.99 | 2.97 | 1.84713e+10 | 1.85957e+10 |\n", - "\n" + "| 2 | 2 | 2018-09-30-2019-09-28 | 260174000000 | 1.61782e+11 | 98392000000 | 1.6217e+10 | 1.8245e+10 | 3.4462e+10 | 6.393e+10 | 1.807e+09 | 6.5737e+10 | 1.0481e+10 | 55256000000 | 2.99 | 2.97 | 1.84713e+10 | 1.85957e+10 |\n" ] } ], @@ -740,13 +734,13 @@ "id": "d0200ea4", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# QnA over Multiple Tables \n", "\n", - "We now make the task for the Agent more complicated, by asking it a question that answer can be computed only by retrieving relevant information from multiple tables: \n", + "We now make the task for the Agent more complicated by asking a question that can be only answered by retrieving relevant information from multiple tables: \n", "\n", - "- Q: What is the ratio of the largest stockholders equity to the smallest revenue?\n", + "* Q: What is the ratio of the largest stockholders equity to the smallest revenue?\n", "\n", "As you will see below, this question can be obtained only by accessing both the balance sheet and the income statement. \n", "\n" @@ -819,8 +813,7 @@ "|---:|-------------:|:-----------|----------------------------------------:|------------------------------:|-------------------------------:|---------------:|-----------------------------:|---------------------:|----------------:|---------------------------------:|-------------------------------:|------------------------:|-------------------:|--------------:|-------------------------:|--------------------------:|---------------------------------------:|------------------:|----------------------:|---------------------:|-------------------------:|-----------------------------:|------------------------:|--------------:|------------------------------:|-----------------------------------------------:|-------------------------------------:|--------------------------------------------------:|---------------------:|-----------------------------------:|\n", "| 0 | 0 | 2017-09-30 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 134047000000 | nan |\n", "| 1 | 1 | 2018-09-29 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 107147000000 | nan |\n", - "| 2 | 2 | 2019-09-28 | 4.8844e+10 | 5.1713e+10 | 2.2926e+10 | 4.106e+09 | 2.2878e+10 | 1.2352e+10 | 1.62819e+11 | 1.05341e+11 | 3.7378e+10 | 3.2978e+10 | 1.75697e+11 | 3.38516e+11 | 4.6236e+10 | 3.772e+10 | 5.522e+09 | 5.98e+09 | 1.026e+10 | 1.05718e+11 | 9.1807e+10 | 5.0503e+10 | 1.4231e+11 | 2.48028e+11 | 0 | 4.5174e+10 | 4.5898e+10 | -5.84e+08 | 90488000000 | 3.38516e+11 |\n", - "\n" + "| 2 | 2 | 2019-09-28 | 4.8844e+10 | 5.1713e+10 | 2.2926e+10 | 4.106e+09 | 2.2878e+10 | 1.2352e+10 | 1.62819e+11 | 1.05341e+11 | 3.7378e+10 | 3.2978e+10 | 1.75697e+11 | 3.38516e+11 | 4.6236e+10 | 3.772e+10 | 5.522e+09 | 5.98e+09 | 1.026e+10 | 1.05718e+11 | 9.1807e+10 | 5.0503e+10 | 1.4231e+11 | 2.48028e+11 | 0 | 4.5174e+10 | 4.5898e+10 | -5.84e+08 | 90488000000 | 3.38516e+11 |\n" ] } ], @@ -873,14 +866,14 @@ "id": "571c8c96", "metadata": {}, "source": [ - "\n", + "\n", "\n", "# Error Resilience\n", "\n", - "In the previous example over single table, the model successfully answered your questions. However, the model may not always have access to the preview of the data. You will see that when we remove the preview from the preamble, the model is run into an error and not produce the answer. We will solve this problem with two different ways: \n", + "In the previous example over single table, the model successfully answered your questions. However, the model may not always have access to the preview of the data. You will see that when we remove the preview from the preamble, the model runs into an error and is not produce the answer. We will solve this problem with two different ways: \n", "\n", - "1. Asking the model to keep trying until it fixes the issue. \n", - "2. Giving the model another tool to view the data and telling it to preview the data before writing code. \n", + "* Asking the model to keep trying until it fixes the issue. \n", + "* Giving the model another tool to view the data and telling it to preview the data before writing code. \n", "\n", "You will see that the second method is able to come to the answer with fewer steps. \n" ] diff --git a/notebooks/agents/sql_agent/sql_agent.ipynb b/notebooks/agents/sql_agent/sql_agent.ipynb index 62ec38d8..76b525f0 100644 --- a/notebooks/agents/sql_agent/sql_agent.ipynb +++ b/notebooks/agents/sql_agent/sql_agent.ipynb @@ -1,13 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "id": "5c0d5271-8d35-4471-b667-265695cbf11a", - "metadata": {}, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "id": "1d71f595-01ef-4c24-99eb-81b01eec048b", @@ -16,10 +8,10 @@ "# Notebook Overview\n", "\n", "## Motivation\n", - "Enterprise customers often store and handle information in relational databases but querying such databases effectively requires bespoke knowledge of the underlying database structure as well as strong SQL coding skills. One way to address these challenges is to build an LLM agent capable of generating and executing SQL queries based on natural language. For example If a user asks: ``what are the top 4 rows in table X``, the agent should be able to generate ``SELECT * FROM X LIMIT 4``, execute this query and return the output to the user. \n", + "Enterprise customers often store and handle information in relational databases but querying such databases effectively requires bespoke knowledge of the underlying database structure as well as strong SQL coding skills. One way to address these challenges is to build an LLM agent capable of generating and executing SQL queries based on natural language. For example, if a user asks: ``what are the top 4 rows in table X``, the agent should be able to generate ``SELECT * FROM X LIMIT 4``, execute this query and return the output to the user. \n", "\n", "## Objective\n", - "In this notebook we explore how to setup a [Cohere ReAct Agent](https://github.com/langchain-ai/langchain-cohere/blob/main/libs/cohere/langchain_cohere/cohere_agent.py) to answer questions over SQL Databases. We show how this can be done seamlessly with langchain's existing SQLDBToolkit.\n", + "In this notebook we explore how to setup a [Cohere ReAct Agent](https://github.com/langchain-ai/langchain-cohere/blob/main/libs/cohere/langchain_cohere/cohere_agent.py) to answer questions over SQL Databases. We show how this can be done seamlessly with langchain's existing [SQLDBToolkit](https://python.langchain.com/v0.1/docs/integrations/toolkits/sql_database/).\n", "\n", "## Table of Contents\n", "\n", @@ -32,17 +24,20 @@ "cell_type": "markdown", "id": "68e373fd", "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "source": [ - "\n", + "\n", "# Toolkit Setup\n", "\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "id": "bce0ca82-fc00-40bb-9d0e-a274bd2eb8a7", "metadata": { "colab": { @@ -59,22 +54,20 @@ "from langchain_cohere.chat_models import ChatCohere\n", "from langchain_community.utilities.sql_database import SQLDatabase\n", "from langchain_community.agent_toolkits import SQLDatabaseToolkit\n", - "import os" + "import os\n", + "import json" ] }, { "cell_type": "code", "execution_count": 2, "id": "76287bf9-d98d-4a34-84c8-46134b85de53", - "metadata": {}, + "metadata": { + "is_executing": true + }, "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "\n", "#!pip install --quiet langchain langchain_cohere langchain_experimental --upgrade" ] }, @@ -96,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "6195f401-f0be-4a31-ab9f-80e722bb0fbb", "metadata": {}, "outputs": [], @@ -107,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 23, "id": "936212a7-fda6-4e12-a5e3-2fdd373660ae", "metadata": {}, "outputs": [ @@ -116,31 +109,21 @@ "output_type": "stream", "text": [ "**List of pre-defined Langchain Tools**\n", - "['sql_db_query', 'sql_db_schema', 'sql_db_list_tables', 'sql_db_query_checker']\n", - "\n", - "**Context to pass to LLM on tables**\n", - "{'table_info': '\\nCREATE TABLE \"Album\" (\\n\\t\"AlbumId\" INTEGER NOT NULL, \\n\\t\"Title\" NVARCHAR(160) NOT NULL, \\n\\t\"ArtistId\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"AlbumId\"), \\n\\tFOREIGN KEY(\"ArtistId\") REFERENCES \"Artist\" (\"ArtistId\")\\n)\\n\\n/*\\n3 rows from Album table:\\nAlbumId\\tTitle\\tArtistId\\n1\\tFor Those About To Rock We Salute You\\t1\\n2\\tBalls to the Wall\\t2\\n3\\tRestless and Wild\\t2\\n*/\\n\\n\\nCREATE TABLE \"Artist\" (\\n\\t\"ArtistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"ArtistId\")\\n)\\n\\n/*\\n3 rows from Artist table:\\nArtistId\\tName\\n1\\tAC/DC\\n2\\tAccept\\n3\\tAerosmith\\n*/\\n\\n\\nCREATE TABLE \"Customer\" (\\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"FirstName\" NVARCHAR(40) NOT NULL, \\n\\t\"LastName\" NVARCHAR(20) NOT NULL, \\n\\t\"Company\" NVARCHAR(80), \\n\\t\"Address\" NVARCHAR(70), \\n\\t\"City\" NVARCHAR(40), \\n\\t\"State\" NVARCHAR(40), \\n\\t\"Country\" NVARCHAR(40), \\n\\t\"PostalCode\" NVARCHAR(10), \\n\\t\"Phone\" NVARCHAR(24), \\n\\t\"Fax\" NVARCHAR(24), \\n\\t\"Email\" NVARCHAR(60) NOT NULL, \\n\\t\"SupportRepId\" INTEGER, \\n\\tPRIMARY KEY (\"CustomerId\"), \\n\\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\\n)\\n\\n/*\\n3 rows from Customer table:\\nCustomerId\\tFirstName\\tLastName\\tCompany\\tAddress\\tCity\\tState\\tCountry\\tPostalCode\\tPhone\\tFax\\tEmail\\tSupportRepId\\n1\\tLuís\\tGonçalves\\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\\tAv. Brigadeiro Faria Lima, 2170\\tSão José dos Campos\\tSP\\tBrazil\\t12227-000\\t+55 (12) 3923-5555\\t+55 (12) 3923-5566\\tluisg@embraer.com.br\\t3\\n2\\tLeonie\\tKöhler\\tNone\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t+49 0711 2842222\\tNone\\tleonekohler@surfeu.de\\t5\\n3\\tFrançois\\tTremblay\\tNone\\t1498 rue Bélanger\\tMontréal\\tQC\\tCanada\\tH2G 1A7\\t+1 (514) 721-4711\\tNone\\tftremblay@gmail.com\\t3\\n*/\\n\\n\\nCREATE TABLE \"Employee\" (\\n\\t\"EmployeeId\" INTEGER NOT NULL, \\n\\t\"LastName\" NVARCHAR(20) NOT NULL, \\n\\t\"FirstName\" NVARCHAR(20) NOT NULL, \\n\\t\"Title\" NVARCHAR(30), \\n\\t\"ReportsTo\" INTEGER, \\n\\t\"BirthDate\" DATETIME, \\n\\t\"HireDate\" DATETIME, \\n\\t\"Address\" NVARCHAR(70), \\n\\t\"City\" NVARCHAR(40), \\n\\t\"State\" NVARCHAR(40), \\n\\t\"Country\" NVARCHAR(40), \\n\\t\"PostalCode\" NVARCHAR(10), \\n\\t\"Phone\" NVARCHAR(24), \\n\\t\"Fax\" NVARCHAR(24), \\n\\t\"Email\" NVARCHAR(60), \\n\\tPRIMARY KEY (\"EmployeeId\"), \\n\\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\\n)\\n\\n/*\\n3 rows from Employee table:\\nEmployeeId\\tLastName\\tFirstName\\tTitle\\tReportsTo\\tBirthDate\\tHireDate\\tAddress\\tCity\\tState\\tCountry\\tPostalCode\\tPhone\\tFax\\tEmail\\n1\\tAdams\\tAndrew\\tGeneral Manager\\tNone\\t1962-02-18 00:00:00\\t2002-08-14 00:00:00\\t11120 Jasper Ave NW\\tEdmonton\\tAB\\tCanada\\tT5K 2N1\\t+1 (780) 428-9482\\t+1 (780) 428-3457\\tandrew@chinookcorp.com\\n2\\tEdwards\\tNancy\\tSales Manager\\t1\\t1958-12-08 00:00:00\\t2002-05-01 00:00:00\\t825 8 Ave SW\\tCalgary\\tAB\\tCanada\\tT2P 2T3\\t+1 (403) 262-3443\\t+1 (403) 262-3322\\tnancy@chinookcorp.com\\n3\\tPeacock\\tJane\\tSales Support Agent\\t2\\t1973-08-29 00:00:00\\t2002-04-01 00:00:00\\t1111 6 Ave SW\\tCalgary\\tAB\\tCanada\\tT2P 5M5\\t+1 (403) 262-3443\\t+1 (403) 262-6712\\tjane@chinookcorp.com\\n*/\\n\\n\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Invoice\" (\\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"InvoiceDate\" DATETIME NOT NULL, \\n\\t\"BillingAddress\" NVARCHAR(70), \\n\\t\"BillingCity\" NVARCHAR(40), \\n\\t\"BillingState\" NVARCHAR(40), \\n\\t\"BillingCountry\" NVARCHAR(40), \\n\\t\"BillingPostalCode\" NVARCHAR(10), \\n\\t\"Total\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceId\"), \\n\\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\\n)\\n\\n/*\\n3 rows from Invoice table:\\nInvoiceId\\tCustomerId\\tInvoiceDate\\tBillingAddress\\tBillingCity\\tBillingState\\tBillingCountry\\tBillingPostalCode\\tTotal\\n1\\t2\\t2021-01-01 00:00:00\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t1.98\\n2\\t4\\t2021-01-02 00:00:00\\tUllevålsveien 14\\tOslo\\tNone\\tNorway\\t0171\\t3.96\\n3\\t8\\t2021-01-03 00:00:00\\tGrétrystraat 63\\tBrussels\\tNone\\tBelgium\\t1000\\t5.94\\n*/\\n\\n\\nCREATE TABLE \"InvoiceLine\" (\\n\\t\"InvoiceLineId\" INTEGER NOT NULL, \\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\n\\t\"Quantity\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceLineId\"), \\n\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\n\\tFOREIGN KEY(\"InvoiceId\") REFERENCES \"Invoice\" (\"InvoiceId\")\\n)\\n\\n/*\\n3 rows from InvoiceLine table:\\nInvoiceLineId\\tInvoiceId\\tTrackId\\tUnitPrice\\tQuantity\\n1\\t1\\t2\\t0.99\\t1\\n2\\t1\\t4\\t0.99\\t1\\n3\\t2\\t6\\t0.99\\t1\\n*/\\n\\n\\nCREATE TABLE \"MediaType\" (\\n\\t\"MediaTypeId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"MediaTypeId\")\\n)\\n\\n/*\\n3 rows from MediaType table:\\nMediaTypeId\\tName\\n1\\tMPEG audio file\\n2\\tProtected AAC audio file\\n3\\tProtected MPEG-4 video file\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/\\n\\n\\nCREATE TABLE \"PlaylistTrack\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"PlaylistId\", \"TrackId\"), \\n\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\n\\tFOREIGN KEY(\"PlaylistId\") REFERENCES \"Playlist\" (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from PlaylistTrack table:\\nPlaylistId\\tTrackId\\n1\\t3402\\n1\\t3389\\n1\\t3390\\n*/\\n\\n\\nCREATE TABLE \"Track\" (\\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(200) NOT NULL, \\n\\t\"AlbumId\" INTEGER, \\n\\t\"MediaTypeId\" INTEGER NOT NULL, \\n\\t\"GenreId\" INTEGER, \\n\\t\"Composer\" NVARCHAR(220), \\n\\t\"Milliseconds\" INTEGER NOT NULL, \\n\\t\"Bytes\" INTEGER, \\n\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"TrackId\"), \\n\\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \\n\\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \\n\\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\\n)\\n\\n/*\\n3 rows from Track table:\\nTrackId\\tName\\tAlbumId\\tMediaTypeId\\tGenreId\\tComposer\\tMilliseconds\\tBytes\\tUnitPrice\\n1\\tFor Those About To Rock (We Salute You)\\t1\\t1\\t1\\tAngus Young, Malcolm Young, Brian Johnson\\t343719\\t11170334\\t0.99\\n2\\tBalls to the Wall\\t2\\t2\\t1\\tU. Dirkschneider, W. Hoffmann, H. Frank, P. Baltes, S. Kaufmann, G. Hoffmann\\t342562\\t5510424\\t0.99\\n3\\tFast As a Shark\\t3\\t2\\t1\\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\\t230619\\t3990994\\t0.99\\n*/', 'table_names': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}\n" + "['sql_db_query', 'sql_db_schema', 'sql_db_list_tables', 'sql_db_query_checker']\n" ] } ], "source": [ - "\n", "DB_NAME='Chinook.db'\n", "MODEL=\"command-r-plus\"\n", - "\n", "llm = ChatCohere(model=MODEL, temperature=0.1,verbose=True)\n", "db = SQLDatabase.from_uri(f\"sqlite:///{DB_NAME}\")\n", - "\n", - "\n", "toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n", "context = toolkit.get_context()\n", "tools = toolkit.get_tools()\n", "\n", "print('**List of pre-defined Langchain Tools**')\n", - "print([tool.name for tool in tools])\n", - "print('')\n", - "print('**Context to pass to LLM on tables**')\n", - "print(context)" + "print([tool.name for tool in tools])" ] }, { @@ -148,23 +131,21 @@ "id": "7554c397-76ae-46c8-9c76-b906f926febf", "metadata": {}, "source": [ - "\n", + "\n", "# SQL Agent\n", "\n", - "we follow the general cohere react agent setup in Langchain to build our SQL agent." + "We follow the general cohere react agent setup in Langchain to build our SQL agent." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 28, "id": "9be6f9eb-b1ba-4a4f-a5f3-5b775f0db69f", "metadata": {}, "outputs": [], "source": [ - "\n", "# define the prompt template\n", "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "\n", "# instantiate the ReAct agent\n", "agent = create_cohere_react_agent(\n", " llm=llm,\n", @@ -175,8 +156,7 @@ " tools=tools,\n", " verbose=True,\n", " return_intermediate_steps=True\n", - " )\n", - "\n" + " )" ] }, { @@ -191,65 +171,65 @@ "text": [ "\n", "\n", - "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", - "\u001B[32;1m\u001B[1;3m\n", - "I will use the sql_db_list_tables tool to find out what tables are available.\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will use the sql_db_list_tables tool to find out which tables are available.\n", "{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\n", - "\u001B[0m\u001B[38;5;200m\u001B[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: The following tables are available: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track.\n", - "Grounded answer: The following tables are available: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track.\u001B[0m\n", + "Grounded answer: The following tables are available: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track.\u001b[0m\n", "\n", - "\u001B[1m> Finished chain.\u001B[0m\n" + "\u001b[1m> Finished chain.\u001b[0m\n" ] - }, - { - "data": { - "text/plain": [ - "{'input': 'what tables are available?',\n", - " 'output': 'The following tables are available: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track.',\n", - " 'citations': [CohereCitation(start=36, end=41, text='Album', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=43, end=49, text='Artist', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=51, end=59, text='Customer', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=61, end=69, text='Employee', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=71, end=76, text='Genre', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=78, end=85, text='Invoice', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=87, end=98, text='InvoiceLine', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=100, end=109, text='MediaType', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=111, end=119, text='Playlist', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=121, end=134, text='PlaylistTrack', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}]),\n", - " CohereCitation(start=136, end=141, text='Track', documents=[{'output': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}])],\n", - " 'intermediate_steps': [(AgentActionMessageLog(tool='sql_db_list_tables', tool_input={'tool_input': ''}, log=\"\\nI will use the sql_db_list_tables tool to find out what tables are available.\\n{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\\n\", message_log=[AIMessage(content='\\nPlan: I will use the sql_db_list_tables tool to find out what tables are available.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_list_tables\",\\n \"parameters\": {\\n \"tool_input\": \"\"\\n }\\n }\\n]\\n```')]),\n", - " 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track')]}" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "agent_executor.invoke({\n", + "output=agent_executor.invoke({\n", " \"input\": 'what tables are available?',\n", "})" ] }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e7118c7a-f92b-4cbc-81b5-7d005801027c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The following tables are available: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track.\n" + ] + } + ], + "source": [ + "print(output['output'])" + ] + }, { "cell_type": "markdown", "id": "8a1fc000", "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "source": [ - "The agent uses the list_tables tool to effectively highlight all the tables in the DB" + "The agent uses the list_tables tool to effectively highlight all the tables in the DB." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "77a3f5ac", "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [ { @@ -258,11 +238,11 @@ "text": [ "\n", "\n", - "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", - "\u001B[32;1m\u001B[1;3m\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", "I will use the sql_db_schema tool to find the first row of the Playlist and Genre tables.\n", "{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Playlist, Genre'}}\n", - "\u001B[0m\u001B[33;1m\u001B[1;3m\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m\n", "CREATE TABLE \"Genre\" (\n", "\t\"GenreId\" INTEGER NOT NULL, \n", "\t\"Name\" NVARCHAR(120), \n", @@ -290,73 +270,80 @@ "1\tMusic\n", "2\tMovies\n", "3\tTV Shows\n", - "*/\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", + "*/\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: Here is the first row of the Genre table:\n", "\n", "| GenreId | Name |\n", - "| --- | --- |\n", + "|---|---|\n", "| 1 | Rock |\n", "\n", "Here is the first row of the Playlist table:\n", "\n", "| PlaylistId | Name |\n", - "| --- | --- |\n", + "|---|---|\n", "| 1 | Music |\n", "Grounded answer: Here is the first row of the Genre table:\n", "\n", "| GenreId | Name |\n", - "| --- | --- |\n", + "|---|---|\n", "| 1 | Rock |\n", "\n", "Here is the first row of the Playlist table:\n", "\n", "| PlaylistId | Name |\n", - "| --- | --- |\n", - "| 1 | Music |\u001B[0m\n", + "|---|---|\n", + "| 1 | Music |\u001b[0m\n", "\n", - "\u001B[1m> Finished chain.\u001B[0m\n" + "\u001b[1m> Finished chain.\u001b[0m\n" ] - }, - { - "data": { - "text/plain": [ - "{'input': 'show the first row of the Playlist and Genre tables?',\n", - " 'output': 'Here is the first row of the Genre table:\\n\\n| GenreId | Name |\\n| --- | --- |\\n| 1 | Rock |\\n\\nHere is the first row of the Playlist table:\\n\\n| PlaylistId | Name |\\n| --- | --- |\\n| 1 | Music |',\n", - " 'citations': [CohereCitation(start=45, end=52, text='GenreId', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=55, end=59, text='Name', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=78, end=79, text='1', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=82, end=86, text='Rock', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=138, end=148, text='PlaylistId', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=151, end=155, text='Name', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=174, end=175, text='1', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}]),\n", - " CohereCitation(start=178, end=183, text='Music', documents=[{'output': '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/'}])],\n", - " 'intermediate_steps': [(AgentActionMessageLog(tool='sql_db_schema', tool_input={'table_names': 'Playlist, Genre'}, log=\"\\nI will use the sql_db_schema tool to find the first row of the Playlist and Genre tables.\\n{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Playlist, Genre'}}\\n\", message_log=[AIMessage(content='\\nPlan: I will use the sql_db_schema tool to find the first row of the Playlist and Genre tables.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_schema\",\\n \"parameters\": {\\n \"table_names\": \"Playlist, Genre\"\\n }\\n }\\n]\\n```')]),\n", - " '\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/')]}" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "agent_executor.invoke({\n", + "output=agent_executor.invoke({\n", " \"input\": 'show the first row of the Playlist and Genre tables?',\n", "})" ] }, + { + "cell_type": "code", + "execution_count": 18, + "id": "55556951-3643-4494-b4bd-6e1c952b9e6b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Here is the first row of the Genre table:\n", + "\n", + "| GenreId | Name |\n", + "|---|---|\n", + "| 1 | Rock |\n", + "\n", + "Here is the first row of the Playlist table:\n", + "\n", + "| PlaylistId | Name |\n", + "|---|---|\n", + "| 1 | Music |\n" + ] + } + ], + "source": [ + "print(output['output'])" + ] + }, { "cell_type": "markdown", "id": "3e77d393-7fd8-42df-8ed2-59badb3b6d5b", "metadata": {}, "source": [ - "Here we see that the tool takes a list of tables to query the sql_db_schema tool to retrieve the various schemas" + "Here we see that the tool takes a list of tables to query the sql_db_schema tool to retrieve the various schemas." ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "4466e2b1-8cd7-4e50-aab4-8a6d9f809491", "metadata": {}, "outputs": [ @@ -366,24 +353,24 @@ "text": [ "\n", "\n", - "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", - "\u001B[32;1m\u001B[1;3m\n", - "I will search for the number of invoices per country and then write an answer based on the results.\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will search for the number of invoices per country and then write an answer.\n", "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3mError: (sqlite3.OperationalError) no such table: invoices\n", + "\u001b[0m\u001b[36;1m\u001b[1;3mError: (sqlite3.OperationalError) no such table: invoices\n", "[SQL: SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC]\n", - "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I received an error message. I will now use the sql_db_list_tables tool to find out the name of the table containing the invoices data.\n", + "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I received an error message. I will now use the sql_db_list_tables tool to find out the correct table name.\n", "{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\n", - "\u001B[0m\u001B[38;5;200m\u001B[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I found out that the table name is 'Invoice'. I will now rewrite my query and run it again.\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I found out that the correct table name is 'Invoice'. I will now rewrite my query and run it again.\n", "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3mError: (sqlite3.OperationalError) no such column: country\n", + "\u001b[0m\u001b[36;1m\u001b[1;3mError: (sqlite3.OperationalError) no such column: country\n", "[SQL: SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC]\n", - "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I received another error message. I will now use the sql_db_schema tool to find out the column names in the 'Invoice' table.\n", + "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I received another error message. I will now use the sql_db_schema tool to find out the correct column name.\n", "{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Invoice'}}\n", - "\u001B[0m\u001B[33;1m\u001B[1;3m\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m\n", "CREATE TABLE \"Invoice\" (\n", "\t\"InvoiceId\" INTEGER NOT NULL, \n", "\t\"CustomerId\" INTEGER NOT NULL, \n", @@ -404,59 +391,53 @@ "1\t2\t2021-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n", "2\t4\t2021-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n", "3\t8\t2021-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n", - "*/\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I found out that the column name for country is 'BillingCountry'. I will now rewrite my query and run it again.\n", - "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT BillingCountry AS country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3m[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 1,3,4\n", + "*/\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I found out that the correct column name is 'BillingCountry'. I will now rewrite my query and run it again.\n", + "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT BillingCountry AS country, COUNT(*) AS invoice_count FROM Invoice GROUP BY BillingCountry ORDER BY invoice_count DESC'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,3,4\n", "Cited Documents: 4\n", "Answer: The countries with the most invoices are the USA (91), Canada (56), and France (35).\n", - "Grounded answer: The countries with the most invoices are the USA (91), Canada (56), and France (35).\u001B[0m\n", + "Grounded answer: The countries with the most invoices are the USA (91), Canada (56), and France (35).\u001b[0m\n", "\n", - "\u001B[1m> Finished chain.\u001B[0m\n" + "\u001b[1m> Finished chain.\u001b[0m\n" ] - }, - { - "data": { - "text/plain": [ - "{'input': 'which countries have the most invoices?',\n", - " 'output': 'The countries with the most invoices are the USA (91), Canada (56), and France (35).',\n", - " 'citations': [CohereCitation(start=45, end=52, text='USA (91', documents=[{'output': \"[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\"}]),\n", - " CohereCitation(start=55, end=65, text='Canada (56', documents=[{'output': \"[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\"}]),\n", - " CohereCitation(start=72, end=82, text='France (35', documents=[{'output': \"[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\"}])],\n", - " 'intermediate_steps': [(AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC'}, log=\"\\nI will search for the number of invoices per country and then write an answer based on the results.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC'}}\\n\", message_log=[AIMessage(content='\\nPlan: I will search for the number of invoices per country and then write an answer based on the results.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC\"\\n }\\n }\\n]\\n```')]),\n", - " 'Error: (sqlite3.OperationalError) no such table: invoices\\n[SQL: SELECT country, COUNT(*) AS invoice_count FROM invoices GROUP BY country ORDER BY invoice_count DESC]\\n(Background on this error at: https://sqlalche.me/e/20/e3q8)'),\n", - " (AgentActionMessageLog(tool='sql_db_list_tables', tool_input={'tool_input': ''}, log=\"\\nI received an error message. I will now use the sql_db_list_tables tool to find out the name of the table containing the invoices data.\\n{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\\n\", message_log=[AIMessage(content='\\nReflection: I received an error message. I will now use the sql_db_list_tables tool to find out the name of the table containing the invoices data.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_list_tables\",\\n \"parameters\": {\\n \"tool_input\": \"\"\\n }\\n }\\n]\\n```')]),\n", - " 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'),\n", - " (AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}, log=\"\\nI found out that the table name is 'Invoice'. I will now rewrite my query and run it again.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}}\\n\", message_log=[AIMessage(content='\\nReflection: I found out that the table name is \\'Invoice\\'. I will now rewrite my query and run it again.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC\"\\n }\\n }\\n]\\n```')]),\n", - " 'Error: (sqlite3.OperationalError) no such column: country\\n[SQL: SELECT country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC]\\n(Background on this error at: https://sqlalche.me/e/20/e3q8)'),\n", - " (AgentActionMessageLog(tool='sql_db_schema', tool_input={'table_names': 'Invoice'}, log=\"\\nI received another error message. I will now use the sql_db_schema tool to find out the column names in the 'Invoice' table.\\n{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Invoice'}}\\n\", message_log=[AIMessage(content='\\nReflection: I received another error message. I will now use the sql_db_schema tool to find out the column names in the \\'Invoice\\' table.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_schema\",\\n \"parameters\": {\\n \"table_names\": \"Invoice\"\\n }\\n }\\n]\\n```')]),\n", - " '\\nCREATE TABLE \"Invoice\" (\\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"InvoiceDate\" DATETIME NOT NULL, \\n\\t\"BillingAddress\" NVARCHAR(70), \\n\\t\"BillingCity\" NVARCHAR(40), \\n\\t\"BillingState\" NVARCHAR(40), \\n\\t\"BillingCountry\" NVARCHAR(40), \\n\\t\"BillingPostalCode\" NVARCHAR(10), \\n\\t\"Total\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceId\"), \\n\\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\\n)\\n\\n/*\\n3 rows from Invoice table:\\nInvoiceId\\tCustomerId\\tInvoiceDate\\tBillingAddress\\tBillingCity\\tBillingState\\tBillingCountry\\tBillingPostalCode\\tTotal\\n1\\t2\\t2021-01-01 00:00:00\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t1.98\\n2\\t4\\t2021-01-02 00:00:00\\tUllevålsveien 14\\tOslo\\tNone\\tNorway\\t0171\\t3.96\\n3\\t8\\t2021-01-03 00:00:00\\tGrétrystraat 63\\tBrussels\\tNone\\tBelgium\\t1000\\t5.94\\n*/'),\n", - " (AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT BillingCountry AS country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}, log=\"\\nI found out that the column name for country is 'BillingCountry'. I will now rewrite my query and run it again.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT BillingCountry AS country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC'}}\\n\", message_log=[AIMessage(content='\\nReflection: I found out that the column name for country is \\'BillingCountry\\'. I will now rewrite my query and run it again.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT BillingCountry AS country, COUNT(*) AS invoice_count FROM Invoice GROUP BY country ORDER BY invoice_count DESC\"\\n }\\n }\\n]\\n```')]),\n", - " \"[('USA', 91), ('Canada', 56), ('France', 35), ('Brazil', 35), ('Germany', 28), ('United Kingdom', 21), ('Portugal', 14), ('Czech Republic', 14), ('India', 13), ('Sweden', 7), ('Spain', 7), ('Poland', 7), ('Norway', 7), ('Netherlands', 7), ('Italy', 7), ('Ireland', 7), ('Hungary', 7), ('Finland', 7), ('Denmark', 7), ('Chile', 7), ('Belgium', 7), ('Austria', 7), ('Australia', 7), ('Argentina', 7)]\")]}" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "agent_executor.invoke({\n", + "output=agent_executor.invoke({\n", " \"input\": 'which countries have the most invoices?',\n", "})" ] }, + { + "cell_type": "code", + "execution_count": 20, + "id": "ca2de5e9-b75a-4eb2-8797-ebaf90edb3bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The countries with the most invoices are the USA (91), Canada (56), and France (35).\n" + ] + } + ], + "source": [ + "print(output['output'])" + ] + }, { "cell_type": "markdown", "id": "634500b5-8980-4ee9-93a3-172130feeb5a", "metadata": {}, "source": [ - "The agent initially makes some errors as it jumps to answer the question using the db_query tool, but it then realizes it needs to figure out what tables it has access to and what they look like. It then fixes the sql code and is able to generate the right answer" + "The agent initially makes some errors as it jumps to answer the question using the db_query tool, but it then realizes it needs to figure out what tables it has access to and what they look like. It then fixes the SQL code and is able to generate the right answer." ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 29, "id": "95144085-9a57-4b7d-ac8e-c0996c0d3e81", "metadata": {}, "outputs": [ @@ -466,19 +447,19 @@ "text": [ "\n", "\n", - "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", - "\u001B[32;1m\u001B[1;3m\n", - "I will search for the customer who has spent the most money and write an answer based on the results.\n", - "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3mError: (sqlite3.OperationalError) no such table: orders\n", - "[SQL: SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;]\n", - "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I received an error message. I will now use the sql_db_list_tables tool to find out which tables are available.\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", + "I will run a SQL query to find the customer who has spent the most money.\n", + "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT customer_name, SUM(total_cost) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3mError: (sqlite3.OperationalError) no such table: orders\n", + "[SQL: SELECT customer_name, SUM(total_cost) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;]\n", + "(Background on this error at: https://sqlalche.me/e/20/e3q8)\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I received an error message saying that there is no table called 'orders'. I will now use the sql_db_list_tables tool to find out what tables are available.\n", "{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\n", - "\u001B[0m\u001B[38;5;200m\u001B[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I found that there is a 'Customer' table and an 'Invoice' table. I will now use the sql_db_schema tool to find out more about these tables.\n", - "{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Customer,Invoice'}}\n", - "\u001B[0m\u001B[33;1m\u001B[1;3m\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I found that there is a table called 'Customer'. I will now use the sql_db_schema tool to find out what columns are in the 'Customer' table.\n", + "{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Customer'}}\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m\n", "CREATE TABLE \"Customer\" (\n", "\t\"CustomerId\" INTEGER NOT NULL, \n", "\t\"FirstName\" NVARCHAR(40) NOT NULL, \n", @@ -503,9 +484,10 @@ "1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n", "2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n", "3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n", - "*/\n", - "\n", - "\n", + "*/\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I found that the 'Customer' table does not contain any information about how much money a customer has spent. I will now use the sql_db_schema tool to find out what columns are in the 'Invoice' table.\n", + "{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Invoice'}}\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m\n", "CREATE TABLE \"Invoice\" (\n", "\t\"InvoiceId\" INTEGER NOT NULL, \n", "\t\"CustomerId\" INTEGER NOT NULL, \n", @@ -526,51 +508,48 @@ "1\t2\t2021-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n", "2\t4\t2021-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n", "3\t8\t2021-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n", - "*/\u001B[0m\u001B[32;1m\u001B[1;3m\n", - "I found that the 'Customer' table contains information about customers, including their names, addresses, and phone numbers. The 'Invoice' table contains information about invoices, including the customer ID, invoice date, and total amount. I will now write a new query to find the customer who has spent the most money.\n", + "*/\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "I found that the 'Invoice' table contains a 'Total' column, which is likely to be the total amount spent by the customer on that invoice. I will now use the sql_db_query tool to find the customer who has spent the most money.\n", "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT c.FirstName, c.LastName, SUM(i.Total) AS total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 1;'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3m[('Helena', 'Holý', 49.62)]\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 1,2,3\n", - "Cited Documents: 3\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[('Helena', 'Holý', 49.62)]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,2,3,4\n", + "Cited Documents: 4\n", "Answer: The best customer is Helena Holý, who has spent a total of 49.62.\n", - "Grounded answer: The best customer is Helena Holý, who has spent a total of 49.62.\u001B[0m\n", + "Grounded answer: The best customer is Helena Holý, who has spent a total of 49.62.\u001b[0m\n", "\n", - "\u001B[1m> Finished chain.\u001B[0m\n" + "\u001b[1m> Finished chain.\u001b[0m\n" ] - }, - { - "data": { - "text/plain": [ - "{'input': 'who is the best customer? The customer who has spent the most money is the best.',\n", - " 'output': 'The best customer is Helena Holý, who has spent a total of 49.62.',\n", - " 'citations': [CohereCitation(start=21, end=32, text='Helena Holý', documents=[{'output': \"[('Helena', 'Holý', 49.62)]\"}]),\n", - " CohereCitation(start=59, end=64, text='49.62', documents=[{'output': \"[('Helena', 'Holý', 49.62)]\"}])],\n", - " 'intermediate_steps': [(AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;'}, log=\"\\nI will search for the customer who has spent the most money and write an answer based on the results.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;'}}\\n\", message_log=[AIMessage(content='\\nPlan: I will search for the customer who has spent the most money and write an answer based on the results.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;\"\\n }\\n }\\n]\\n```')]),\n", - " 'Error: (sqlite3.OperationalError) no such table: orders\\n[SQL: SELECT customer_name, SUM(total_price) AS total_spent FROM orders GROUP BY customer_name ORDER BY total_spent DESC LIMIT 1;]\\n(Background on this error at: https://sqlalche.me/e/20/e3q8)'),\n", - " (AgentActionMessageLog(tool='sql_db_list_tables', tool_input={'tool_input': ''}, log=\"\\nI received an error message. I will now use the sql_db_list_tables tool to find out which tables are available.\\n{'tool_name': 'sql_db_list_tables', 'parameters': {'tool_input': ''}}\\n\", message_log=[AIMessage(content='\\nReflection: I received an error message. I will now use the sql_db_list_tables tool to find out which tables are available.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_list_tables\",\\n \"parameters\": {\\n \"tool_input\": \"\"\\n }\\n }\\n]\\n```')]),\n", - " 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'),\n", - " (AgentActionMessageLog(tool='sql_db_schema', tool_input={'table_names': 'Customer,Invoice'}, log=\"\\nI found that there is a 'Customer' table and an 'Invoice' table. I will now use the sql_db_schema tool to find out more about these tables.\\n{'tool_name': 'sql_db_schema', 'parameters': {'table_names': 'Customer,Invoice'}}\\n\", message_log=[AIMessage(content='\\nReflection: I found that there is a \\'Customer\\' table and an \\'Invoice\\' table. I will now use the sql_db_schema tool to find out more about these tables.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_schema\",\\n \"parameters\": {\\n \"table_names\": \"Customer,Invoice\"\\n }\\n }\\n]\\n```')]),\n", - " '\\nCREATE TABLE \"Customer\" (\\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"FirstName\" NVARCHAR(40) NOT NULL, \\n\\t\"LastName\" NVARCHAR(20) NOT NULL, \\n\\t\"Company\" NVARCHAR(80), \\n\\t\"Address\" NVARCHAR(70), \\n\\t\"City\" NVARCHAR(40), \\n\\t\"State\" NVARCHAR(40), \\n\\t\"Country\" NVARCHAR(40), \\n\\t\"PostalCode\" NVARCHAR(10), \\n\\t\"Phone\" NVARCHAR(24), \\n\\t\"Fax\" NVARCHAR(24), \\n\\t\"Email\" NVARCHAR(60) NOT NULL, \\n\\t\"SupportRepId\" INTEGER, \\n\\tPRIMARY KEY (\"CustomerId\"), \\n\\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\\n)\\n\\n/*\\n3 rows from Customer table:\\nCustomerId\\tFirstName\\tLastName\\tCompany\\tAddress\\tCity\\tState\\tCountry\\tPostalCode\\tPhone\\tFax\\tEmail\\tSupportRepId\\n1\\tLuís\\tGonçalves\\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\\tAv. Brigadeiro Faria Lima, 2170\\tSão José dos Campos\\tSP\\tBrazil\\t12227-000\\t+55 (12) 3923-5555\\t+55 (12) 3923-5566\\tluisg@embraer.com.br\\t3\\n2\\tLeonie\\tKöhler\\tNone\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t+49 0711 2842222\\tNone\\tleonekohler@surfeu.de\\t5\\n3\\tFrançois\\tTremblay\\tNone\\t1498 rue Bélanger\\tMontréal\\tQC\\tCanada\\tH2G 1A7\\t+1 (514) 721-4711\\tNone\\tftremblay@gmail.com\\t3\\n*/\\n\\n\\nCREATE TABLE \"Invoice\" (\\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"InvoiceDate\" DATETIME NOT NULL, \\n\\t\"BillingAddress\" NVARCHAR(70), \\n\\t\"BillingCity\" NVARCHAR(40), \\n\\t\"BillingState\" NVARCHAR(40), \\n\\t\"BillingCountry\" NVARCHAR(40), \\n\\t\"BillingPostalCode\" NVARCHAR(10), \\n\\t\"Total\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceId\"), \\n\\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\\n)\\n\\n/*\\n3 rows from Invoice table:\\nInvoiceId\\tCustomerId\\tInvoiceDate\\tBillingAddress\\tBillingCity\\tBillingState\\tBillingCountry\\tBillingPostalCode\\tTotal\\n1\\t2\\t2021-01-01 00:00:00\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t1.98\\n2\\t4\\t2021-01-02 00:00:00\\tUllevålsveien 14\\tOslo\\tNone\\tNorway\\t0171\\t3.96\\n3\\t8\\t2021-01-03 00:00:00\\tGrétrystraat 63\\tBrussels\\tNone\\tBelgium\\t1000\\t5.94\\n*/'),\n", - " (AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT c.FirstName, c.LastName, SUM(i.Total) AS total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 1;'}, log=\"\\nI found that the 'Customer' table contains information about customers, including their names, addresses, and phone numbers. The 'Invoice' table contains information about invoices, including the customer ID, invoice date, and total amount. I will now write a new query to find the customer who has spent the most money.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT c.FirstName, c.LastName, SUM(i.Total) AS total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 1;'}}\\n\", message_log=[AIMessage(content='\\nReflection: I found that the \\'Customer\\' table contains information about customers, including their names, addresses, and phone numbers. The \\'Invoice\\' table contains information about invoices, including the customer ID, invoice date, and total amount. I will now write a new query to find the customer who has spent the most money.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT c.FirstName, c.LastName, SUM(i.Total) AS total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 1;\"\\n }\\n }\\n]\\n```')]),\n", - " \"[('Helena', 'Holý', 49.62)]\")]}" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "agent_executor.invoke({\n", + "output=agent_executor.invoke({\n", " \"input\": 'who is the best customer? The customer who has spent the most money is the best.',\n", "})" ] }, + { + "cell_type": "code", + "execution_count": 30, + "id": "7274af42-6e58-4a2c-a43b-d1610c5d51e4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The best customer is Helena Holý, who has spent a total of 49.62.\n" + ] + } + ], + "source": [ + "print(output['output'])" + ] + }, { "cell_type": "markdown", "id": "14ca1ab1-1deb-4c25-bc2d-6f047bcb49d9", "metadata": {}, "source": [ - "As you can see, the agent makes an error, but is able to rectify itself. It also manages to generate SQL query over two tables in the database" + "As you can see, the agent makes an error, but is able to rectify itself. It also manages to generate a SQL query over two tables in the database." ] }, { @@ -578,7 +557,7 @@ "id": "1c9ea4d9-8f92-4780-b33e-e348b2fa854f", "metadata": {}, "source": [ - "\n", + "\n", "# SQL Agent with context" ] }, @@ -587,29 +566,249 @@ "id": "1883f0f6-c1b9-41d0-9049-68d2101f8a9e", "metadata": {}, "source": [ - "From our experiments, we have found that passing in additional context to the preamble can help reduce the initial failures. This context is provided by the SQLDBToolkit and contains the first 3 rows of the tables in the Database" + "Generally, passing in additional context to the preamble can help reduce the initial failures. This context is provided by the SQLDBToolkit and contains the first 3 rows of the tables in the Database." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 24, "id": "fd781ff2-ee5f-4fef-b1b4-fde58562383c", "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "{'table_info': '\\nCREATE TABLE \"Album\" (\\n\\t\"AlbumId\" INTEGER NOT NULL, \\n\\t\"Title\" NVARCHAR(160) NOT NULL, \\n\\t\"ArtistId\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"AlbumId\"), \\n\\tFOREIGN KEY(\"ArtistId\") REFERENCES \"Artist\" (\"ArtistId\")\\n)\\n\\n/*\\n3 rows from Album table:\\nAlbumId\\tTitle\\tArtistId\\n1\\tFor Those About To Rock We Salute You\\t1\\n2\\tBalls to the Wall\\t2\\n3\\tRestless and Wild\\t2\\n*/\\n\\n\\nCREATE TABLE \"Artist\" (\\n\\t\"ArtistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"ArtistId\")\\n)\\n\\n/*\\n3 rows from Artist table:\\nArtistId\\tName\\n1\\tAC/DC\\n2\\tAccept\\n3\\tAerosmith\\n*/\\n\\n\\nCREATE TABLE \"Customer\" (\\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"FirstName\" NVARCHAR(40) NOT NULL, \\n\\t\"LastName\" NVARCHAR(20) NOT NULL, \\n\\t\"Company\" NVARCHAR(80), \\n\\t\"Address\" NVARCHAR(70), \\n\\t\"City\" NVARCHAR(40), \\n\\t\"State\" NVARCHAR(40), \\n\\t\"Country\" NVARCHAR(40), \\n\\t\"PostalCode\" NVARCHAR(10), \\n\\t\"Phone\" NVARCHAR(24), \\n\\t\"Fax\" NVARCHAR(24), \\n\\t\"Email\" NVARCHAR(60) NOT NULL, \\n\\t\"SupportRepId\" INTEGER, \\n\\tPRIMARY KEY (\"CustomerId\"), \\n\\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\\n)\\n\\n/*\\n3 rows from Customer table:\\nCustomerId\\tFirstName\\tLastName\\tCompany\\tAddress\\tCity\\tState\\tCountry\\tPostalCode\\tPhone\\tFax\\tEmail\\tSupportRepId\\n1\\tLuís\\tGonçalves\\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\\tAv. Brigadeiro Faria Lima, 2170\\tSão José dos Campos\\tSP\\tBrazil\\t12227-000\\t+55 (12) 3923-5555\\t+55 (12) 3923-5566\\tluisg@embraer.com.br\\t3\\n2\\tLeonie\\tKöhler\\tNone\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t+49 0711 2842222\\tNone\\tleonekohler@surfeu.de\\t5\\n3\\tFrançois\\tTremblay\\tNone\\t1498 rue Bélanger\\tMontréal\\tQC\\tCanada\\tH2G 1A7\\t+1 (514) 721-4711\\tNone\\tftremblay@gmail.com\\t3\\n*/\\n\\n\\nCREATE TABLE \"Employee\" (\\n\\t\"EmployeeId\" INTEGER NOT NULL, \\n\\t\"LastName\" NVARCHAR(20) NOT NULL, \\n\\t\"FirstName\" NVARCHAR(20) NOT NULL, \\n\\t\"Title\" NVARCHAR(30), \\n\\t\"ReportsTo\" INTEGER, \\n\\t\"BirthDate\" DATETIME, \\n\\t\"HireDate\" DATETIME, \\n\\t\"Address\" NVARCHAR(70), \\n\\t\"City\" NVARCHAR(40), \\n\\t\"State\" NVARCHAR(40), \\n\\t\"Country\" NVARCHAR(40), \\n\\t\"PostalCode\" NVARCHAR(10), \\n\\t\"Phone\" NVARCHAR(24), \\n\\t\"Fax\" NVARCHAR(24), \\n\\t\"Email\" NVARCHAR(60), \\n\\tPRIMARY KEY (\"EmployeeId\"), \\n\\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\\n)\\n\\n/*\\n3 rows from Employee table:\\nEmployeeId\\tLastName\\tFirstName\\tTitle\\tReportsTo\\tBirthDate\\tHireDate\\tAddress\\tCity\\tState\\tCountry\\tPostalCode\\tPhone\\tFax\\tEmail\\n1\\tAdams\\tAndrew\\tGeneral Manager\\tNone\\t1962-02-18 00:00:00\\t2002-08-14 00:00:00\\t11120 Jasper Ave NW\\tEdmonton\\tAB\\tCanada\\tT5K 2N1\\t+1 (780) 428-9482\\t+1 (780) 428-3457\\tandrew@chinookcorp.com\\n2\\tEdwards\\tNancy\\tSales Manager\\t1\\t1958-12-08 00:00:00\\t2002-05-01 00:00:00\\t825 8 Ave SW\\tCalgary\\tAB\\tCanada\\tT2P 2T3\\t+1 (403) 262-3443\\t+1 (403) 262-3322\\tnancy@chinookcorp.com\\n3\\tPeacock\\tJane\\tSales Support Agent\\t2\\t1973-08-29 00:00:00\\t2002-04-01 00:00:00\\t1111 6 Ave SW\\tCalgary\\tAB\\tCanada\\tT2P 5M5\\t+1 (403) 262-3443\\t+1 (403) 262-6712\\tjane@chinookcorp.com\\n*/\\n\\n\\nCREATE TABLE \"Genre\" (\\n\\t\"GenreId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"GenreId\")\\n)\\n\\n/*\\n3 rows from Genre table:\\nGenreId\\tName\\n1\\tRock\\n2\\tJazz\\n3\\tMetal\\n*/\\n\\n\\nCREATE TABLE \"Invoice\" (\\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"CustomerId\" INTEGER NOT NULL, \\n\\t\"InvoiceDate\" DATETIME NOT NULL, \\n\\t\"BillingAddress\" NVARCHAR(70), \\n\\t\"BillingCity\" NVARCHAR(40), \\n\\t\"BillingState\" NVARCHAR(40), \\n\\t\"BillingCountry\" NVARCHAR(40), \\n\\t\"BillingPostalCode\" NVARCHAR(10), \\n\\t\"Total\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceId\"), \\n\\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\\n)\\n\\n/*\\n3 rows from Invoice table:\\nInvoiceId\\tCustomerId\\tInvoiceDate\\tBillingAddress\\tBillingCity\\tBillingState\\tBillingCountry\\tBillingPostalCode\\tTotal\\n1\\t2\\t2021-01-01 00:00:00\\tTheodor-Heuss-Straße 34\\tStuttgart\\tNone\\tGermany\\t70174\\t1.98\\n2\\t4\\t2021-01-02 00:00:00\\tUllevålsveien 14\\tOslo\\tNone\\tNorway\\t0171\\t3.96\\n3\\t8\\t2021-01-03 00:00:00\\tGrétrystraat 63\\tBrussels\\tNone\\tBelgium\\t1000\\t5.94\\n*/\\n\\n\\nCREATE TABLE \"InvoiceLine\" (\\n\\t\"InvoiceLineId\" INTEGER NOT NULL, \\n\\t\"InvoiceId\" INTEGER NOT NULL, \\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\n\\t\"Quantity\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"InvoiceLineId\"), \\n\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\n\\tFOREIGN KEY(\"InvoiceId\") REFERENCES \"Invoice\" (\"InvoiceId\")\\n)\\n\\n/*\\n3 rows from InvoiceLine table:\\nInvoiceLineId\\tInvoiceId\\tTrackId\\tUnitPrice\\tQuantity\\n1\\t1\\t2\\t0.99\\t1\\n2\\t1\\t4\\t0.99\\t1\\n3\\t2\\t6\\t0.99\\t1\\n*/\\n\\n\\nCREATE TABLE \"MediaType\" (\\n\\t\"MediaTypeId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"MediaTypeId\")\\n)\\n\\n/*\\n3 rows from MediaType table:\\nMediaTypeId\\tName\\n1\\tMPEG audio file\\n2\\tProtected AAC audio file\\n3\\tProtected MPEG-4 video file\\n*/\\n\\n\\nCREATE TABLE \"Playlist\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(120), \\n\\tPRIMARY KEY (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from Playlist table:\\nPlaylistId\\tName\\n1\\tMusic\\n2\\tMovies\\n3\\tTV Shows\\n*/\\n\\n\\nCREATE TABLE \"PlaylistTrack\" (\\n\\t\"PlaylistId\" INTEGER NOT NULL, \\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\tPRIMARY KEY (\"PlaylistId\", \"TrackId\"), \\n\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\n\\tFOREIGN KEY(\"PlaylistId\") REFERENCES \"Playlist\" (\"PlaylistId\")\\n)\\n\\n/*\\n3 rows from PlaylistTrack table:\\nPlaylistId\\tTrackId\\n1\\t3402\\n1\\t3389\\n1\\t3390\\n*/\\n\\n\\nCREATE TABLE \"Track\" (\\n\\t\"TrackId\" INTEGER NOT NULL, \\n\\t\"Name\" NVARCHAR(200) NOT NULL, \\n\\t\"AlbumId\" INTEGER, \\n\\t\"MediaTypeId\" INTEGER NOT NULL, \\n\\t\"GenreId\" INTEGER, \\n\\t\"Composer\" NVARCHAR(220), \\n\\t\"Milliseconds\" INTEGER NOT NULL, \\n\\t\"Bytes\" INTEGER, \\n\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\n\\tPRIMARY KEY (\"TrackId\"), \\n\\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \\n\\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \\n\\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\\n)\\n\\n/*\\n3 rows from Track table:\\nTrackId\\tName\\tAlbumId\\tMediaTypeId\\tGenreId\\tComposer\\tMilliseconds\\tBytes\\tUnitPrice\\n1\\tFor Those About To Rock (We Salute You)\\t1\\t1\\t1\\tAngus Young, Malcolm Young, Brian Johnson\\t343719\\t11170334\\t0.99\\n2\\tBalls to the Wall\\t2\\t2\\t1\\tU. Dirkschneider, W. Hoffmann, H. Frank, P. Baltes, S. Kaufmann, G. Hoffmann\\t342562\\t5510424\\t0.99\\n3\\tFast As a Shark\\t3\\t2\\t1\\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\\t230619\\t3990994\\t0.99\\n*/',\n", - " 'table_names': 'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track'}" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "**Context to pass to LLM on tables**\n", + "Table Names\n", + "Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n", + "Table Schemas\n", + "\n", + "CREATE TABLE \"Album\" (\n", + "\t\"AlbumId\" INTEGER NOT NULL, \n", + "\t\"Title\" NVARCHAR(160) NOT NULL, \n", + "\t\"ArtistId\" INTEGER NOT NULL, \n", + "\tPRIMARY KEY (\"AlbumId\"), \n", + "\tFOREIGN KEY(\"ArtistId\") REFERENCES \"Artist\" (\"ArtistId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Album table:\n", + "AlbumId\tTitle\tArtistId\n", + "1\tFor Those About To Rock We Salute You\t1\n", + "2\tBalls to the Wall\t2\n", + "3\tRestless and Wild\t2\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Artist\" (\n", + "\t\"ArtistId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"ArtistId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Artist table:\n", + "ArtistId\tName\n", + "1\tAC/DC\n", + "2\tAccept\n", + "3\tAerosmith\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Customer\" (\n", + "\t\"CustomerId\" INTEGER NOT NULL, \n", + "\t\"FirstName\" NVARCHAR(40) NOT NULL, \n", + "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", + "\t\"Company\" NVARCHAR(80), \n", + "\t\"Address\" NVARCHAR(70), \n", + "\t\"City\" NVARCHAR(40), \n", + "\t\"State\" NVARCHAR(40), \n", + "\t\"Country\" NVARCHAR(40), \n", + "\t\"PostalCode\" NVARCHAR(10), \n", + "\t\"Phone\" NVARCHAR(24), \n", + "\t\"Fax\" NVARCHAR(24), \n", + "\t\"Email\" NVARCHAR(60) NOT NULL, \n", + "\t\"SupportRepId\" INTEGER, \n", + "\tPRIMARY KEY (\"CustomerId\"), \n", + "\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Customer table:\n", + "CustomerId\tFirstName\tLastName\tCompany\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\tSupportRepId\n", + "1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n", + "2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n", + "3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Employee\" (\n", + "\t\"EmployeeId\" INTEGER NOT NULL, \n", + "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", + "\t\"FirstName\" NVARCHAR(20) NOT NULL, \n", + "\t\"Title\" NVARCHAR(30), \n", + "\t\"ReportsTo\" INTEGER, \n", + "\t\"BirthDate\" DATETIME, \n", + "\t\"HireDate\" DATETIME, \n", + "\t\"Address\" NVARCHAR(70), \n", + "\t\"City\" NVARCHAR(40), \n", + "\t\"State\" NVARCHAR(40), \n", + "\t\"Country\" NVARCHAR(40), \n", + "\t\"PostalCode\" NVARCHAR(10), \n", + "\t\"Phone\" NVARCHAR(24), \n", + "\t\"Fax\" NVARCHAR(24), \n", + "\t\"Email\" NVARCHAR(60), \n", + "\tPRIMARY KEY (\"EmployeeId\"), \n", + "\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Employee table:\n", + "EmployeeId\tLastName\tFirstName\tTitle\tReportsTo\tBirthDate\tHireDate\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\n", + "1\tAdams\tAndrew\tGeneral Manager\tNone\t1962-02-18 00:00:00\t2002-08-14 00:00:00\t11120 Jasper Ave NW\tEdmonton\tAB\tCanada\tT5K 2N1\t+1 (780) 428-9482\t+1 (780) 428-3457\tandrew@chinookcorp.com\n", + "2\tEdwards\tNancy\tSales Manager\t1\t1958-12-08 00:00:00\t2002-05-01 00:00:00\t825 8 Ave SW\tCalgary\tAB\tCanada\tT2P 2T3\t+1 (403) 262-3443\t+1 (403) 262-3322\tnancy@chinookcorp.com\n", + "3\tPeacock\tJane\tSales Support Agent\t2\t1973-08-29 00:00:00\t2002-04-01 00:00:00\t1111 6 Ave SW\tCalgary\tAB\tCanada\tT2P 5M5\t+1 (403) 262-3443\t+1 (403) 262-6712\tjane@chinookcorp.com\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Genre\" (\n", + "\t\"GenreId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"GenreId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Genre table:\n", + "GenreId\tName\n", + "1\tRock\n", + "2\tJazz\n", + "3\tMetal\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Invoice\" (\n", + "\t\"InvoiceId\" INTEGER NOT NULL, \n", + "\t\"CustomerId\" INTEGER NOT NULL, \n", + "\t\"InvoiceDate\" DATETIME NOT NULL, \n", + "\t\"BillingAddress\" NVARCHAR(70), \n", + "\t\"BillingCity\" NVARCHAR(40), \n", + "\t\"BillingState\" NVARCHAR(40), \n", + "\t\"BillingCountry\" NVARCHAR(40), \n", + "\t\"BillingPostalCode\" NVARCHAR(10), \n", + "\t\"Total\" NUMERIC(10, 2) NOT NULL, \n", + "\tPRIMARY KEY (\"InvoiceId\"), \n", + "\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Invoice table:\n", + "InvoiceId\tCustomerId\tInvoiceDate\tBillingAddress\tBillingCity\tBillingState\tBillingCountry\tBillingPostalCode\tTotal\n", + "1\t2\t2021-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n", + "2\t4\t2021-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n", + "3\t8\t2021-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"InvoiceLine\" (\n", + "\t\"InvoiceLineId\" INTEGER NOT NULL, \n", + "\t\"InvoiceId\" INTEGER NOT NULL, \n", + "\t\"TrackId\" INTEGER NOT NULL, \n", + "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", + "\t\"Quantity\" INTEGER NOT NULL, \n", + "\tPRIMARY KEY (\"InvoiceLineId\"), \n", + "\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \n", + "\tFOREIGN KEY(\"InvoiceId\") REFERENCES \"Invoice\" (\"InvoiceId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from InvoiceLine table:\n", + "InvoiceLineId\tInvoiceId\tTrackId\tUnitPrice\tQuantity\n", + "1\t1\t2\t0.99\t1\n", + "2\t1\t4\t0.99\t1\n", + "3\t2\t6\t0.99\t1\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"MediaType\" (\n", + "\t\"MediaTypeId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"MediaTypeId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from MediaType table:\n", + "MediaTypeId\tName\n", + "1\tMPEG audio file\n", + "2\tProtected AAC audio file\n", + "3\tProtected MPEG-4 video file\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Playlist\" (\n", + "\t\"PlaylistId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"PlaylistId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Playlist table:\n", + "PlaylistId\tName\n", + "1\tMusic\n", + "2\tMovies\n", + "3\tTV Shows\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"PlaylistTrack\" (\n", + "\t\"PlaylistId\" INTEGER NOT NULL, \n", + "\t\"TrackId\" INTEGER NOT NULL, \n", + "\tPRIMARY KEY (\"PlaylistId\", \"TrackId\"), \n", + "\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \n", + "\tFOREIGN KEY(\"PlaylistId\") REFERENCES \"Playlist\" (\"PlaylistId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from PlaylistTrack table:\n", + "PlaylistId\tTrackId\n", + "1\t3402\n", + "1\t3389\n", + "1\t3390\n", + "*/\n", + "\n", + "\n", + "CREATE TABLE \"Track\" (\n", + "\t\"TrackId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(200) NOT NULL, \n", + "\t\"AlbumId\" INTEGER, \n", + "\t\"MediaTypeId\" INTEGER NOT NULL, \n", + "\t\"GenreId\" INTEGER, \n", + "\t\"Composer\" NVARCHAR(220), \n", + "\t\"Milliseconds\" INTEGER NOT NULL, \n", + "\t\"Bytes\" INTEGER, \n", + "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", + "\tPRIMARY KEY (\"TrackId\"), \n", + "\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \n", + "\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \n", + "\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\n", + ")\n", + "\n", + "/*\n", + "3 rows from Track table:\n", + "TrackId\tName\tAlbumId\tMediaTypeId\tGenreId\tComposer\tMilliseconds\tBytes\tUnitPrice\n", + "1\tFor Those About To Rock (We Salute You)\t1\t1\t1\tAngus Young, Malcolm Young, Brian Johnson\t343719\t11170334\t0.99\n", + "2\tBalls to the Wall\t2\t2\t1\tU. Dirkschneider, W. Hoffmann, H. Frank, P. Baltes, S. Kaufmann, G. Hoffmann\t342562\t5510424\t0.99\n", + "3\tFast As a Shark\t3\t2\t1\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\t230619\t3990994\t0.99\n", + "*/\n" + ] } ], "source": [ - "context" + "print('**Context to pass to LLM on tables**')\n", + "print('Table Names')\n", + "print(context['table_names'])\n", + "print('Table Schemas')\n", + "print(context['table_info'])" ] }, { @@ -622,7 +821,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 25, "id": "06913698-60ee-4b10-b28b-6462c565ad63", "metadata": {}, "outputs": [], @@ -644,7 +843,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "id": "ad461d18-6ae9-40b5-8c85-a48ab9aa6bc0", "metadata": {}, "outputs": [ @@ -654,56 +853,51 @@ "text": [ "\n", "\n", - "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n", - "\u001B[32;1m\u001B[1;3m\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3m\n", "I will write a SQL query to find the customer who has spent the most money.\n", - "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT c.CustomerId, c.FirstName, c.LastName, SUM(i.Total) AS TotalSpent\\nFROM Customer c\\nJOIN Invoice i ON c.CustomerId = i.CustomerId\\nGROUP BY c.CustomerId\\nORDER BY TotalSpent DESC\\nLIMIT 1;'}}\n", - "\u001B[0m\u001B[36;1m\u001B[1;3m[(6, 'Helena', 'Holý', 49.62)]\u001B[0m\u001B[32;1m\u001B[1;3mRelevant Documents: 0\n", + "{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT c.FirstName, c.LastName, SUM(i.Total) AS TotalSpent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY TotalSpent DESC LIMIT 1;'}}\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m[('Helena', 'Holý', 49.62)]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", "Cited Documents: 0\n", "Answer: The customer who has spent the most money is Helena Holý.\n", - "Grounded answer: The customer who has spent the most money is Helena Holý.\u001B[0m\n", + "Grounded answer: The customer who has spent the most money is Helena Holý.\u001b[0m\n", "\n", - "\u001B[1m> Finished chain.\u001B[0m\n" + "\u001b[1m> Finished chain.\u001b[0m\n" ] - }, - { - "data": { - "text/plain": [ - "{'input': 'provide the name of the best customer? The customer who has spent the most money is the best.',\n", - " 'preamble': '## Task And Context\\nYou use your advanced complex reasoning capabilities to help people by answering their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You may need to use multiple tools in parallel or sequentially to complete your task. You should focus on serving the user\\'s needs as best you can, which will be wide-ranging.\\n\\n## Style Guide\\nUnless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.\\n\\n## Additional Information\\nYou are an expert who answers the user\\'s question by creating SQL queries and executing them.\\nYou are equipped with a number of relevant SQL tools.\\n\\nHere is information about the database:\\n{\\'table_info\\': \\'\\\\nCREATE TABLE \"Album\" (\\\\n\\\\t\"AlbumId\" INTEGER NOT NULL, \\\\n\\\\t\"Title\" NVARCHAR(160) NOT NULL, \\\\n\\\\t\"ArtistId\" INTEGER NOT NULL, \\\\n\\\\tPRIMARY KEY (\"AlbumId\"), \\\\n\\\\tFOREIGN KEY(\"ArtistId\") REFERENCES \"Artist\" (\"ArtistId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Album table:\\\\nAlbumId\\\\tTitle\\\\tArtistId\\\\n1\\\\tFor Those About To Rock We Salute You\\\\t1\\\\n2\\\\tBalls to the Wall\\\\t2\\\\n3\\\\tRestless and Wild\\\\t2\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Artist\" (\\\\n\\\\t\"ArtistId\" INTEGER NOT NULL, \\\\n\\\\t\"Name\" NVARCHAR(120), \\\\n\\\\tPRIMARY KEY (\"ArtistId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Artist table:\\\\nArtistId\\\\tName\\\\n1\\\\tAC/DC\\\\n2\\\\tAccept\\\\n3\\\\tAerosmith\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Customer\" (\\\\n\\\\t\"CustomerId\" INTEGER NOT NULL, \\\\n\\\\t\"FirstName\" NVARCHAR(40) NOT NULL, \\\\n\\\\t\"LastName\" NVARCHAR(20) NOT NULL, \\\\n\\\\t\"Company\" NVARCHAR(80), \\\\n\\\\t\"Address\" NVARCHAR(70), \\\\n\\\\t\"City\" NVARCHAR(40), \\\\n\\\\t\"State\" NVARCHAR(40), \\\\n\\\\t\"Country\" NVARCHAR(40), \\\\n\\\\t\"PostalCode\" NVARCHAR(10), \\\\n\\\\t\"Phone\" NVARCHAR(24), \\\\n\\\\t\"Fax\" NVARCHAR(24), \\\\n\\\\t\"Email\" NVARCHAR(60) NOT NULL, \\\\n\\\\t\"SupportRepId\" INTEGER, \\\\n\\\\tPRIMARY KEY (\"CustomerId\"), \\\\n\\\\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Customer table:\\\\nCustomerId\\\\tFirstName\\\\tLastName\\\\tCompany\\\\tAddress\\\\tCity\\\\tState\\\\tCountry\\\\tPostalCode\\\\tPhone\\\\tFax\\\\tEmail\\\\tSupportRepId\\\\n1\\\\tLuís\\\\tGonçalves\\\\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\\\\tAv. Brigadeiro Faria Lima, 2170\\\\tSão José dos Campos\\\\tSP\\\\tBrazil\\\\t12227-000\\\\t+55 (12) 3923-5555\\\\t+55 (12) 3923-5566\\\\tluisg@embraer.com.br\\\\t3\\\\n2\\\\tLeonie\\\\tKöhler\\\\tNone\\\\tTheodor-Heuss-Straße 34\\\\tStuttgart\\\\tNone\\\\tGermany\\\\t70174\\\\t+49 0711 2842222\\\\tNone\\\\tleonekohler@surfeu.de\\\\t5\\\\n3\\\\tFrançois\\\\tTremblay\\\\tNone\\\\t1498 rue Bélanger\\\\tMontréal\\\\tQC\\\\tCanada\\\\tH2G 1A7\\\\t+1 (514) 721-4711\\\\tNone\\\\tftremblay@gmail.com\\\\t3\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Employee\" (\\\\n\\\\t\"EmployeeId\" INTEGER NOT NULL, \\\\n\\\\t\"LastName\" NVARCHAR(20) NOT NULL, \\\\n\\\\t\"FirstName\" NVARCHAR(20) NOT NULL, \\\\n\\\\t\"Title\" NVARCHAR(30), \\\\n\\\\t\"ReportsTo\" INTEGER, \\\\n\\\\t\"BirthDate\" DATETIME, \\\\n\\\\t\"HireDate\" DATETIME, \\\\n\\\\t\"Address\" NVARCHAR(70), \\\\n\\\\t\"City\" NVARCHAR(40), \\\\n\\\\t\"State\" NVARCHAR(40), \\\\n\\\\t\"Country\" NVARCHAR(40), \\\\n\\\\t\"PostalCode\" NVARCHAR(10), \\\\n\\\\t\"Phone\" NVARCHAR(24), \\\\n\\\\t\"Fax\" NVARCHAR(24), \\\\n\\\\t\"Email\" NVARCHAR(60), \\\\n\\\\tPRIMARY KEY (\"EmployeeId\"), \\\\n\\\\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Employee table:\\\\nEmployeeId\\\\tLastName\\\\tFirstName\\\\tTitle\\\\tReportsTo\\\\tBirthDate\\\\tHireDate\\\\tAddress\\\\tCity\\\\tState\\\\tCountry\\\\tPostalCode\\\\tPhone\\\\tFax\\\\tEmail\\\\n1\\\\tAdams\\\\tAndrew\\\\tGeneral Manager\\\\tNone\\\\t1962-02-18 00:00:00\\\\t2002-08-14 00:00:00\\\\t11120 Jasper Ave NW\\\\tEdmonton\\\\tAB\\\\tCanada\\\\tT5K 2N1\\\\t+1 (780) 428-9482\\\\t+1 (780) 428-3457\\\\tandrew@chinookcorp.com\\\\n2\\\\tEdwards\\\\tNancy\\\\tSales Manager\\\\t1\\\\t1958-12-08 00:00:00\\\\t2002-05-01 00:00:00\\\\t825 8 Ave SW\\\\tCalgary\\\\tAB\\\\tCanada\\\\tT2P 2T3\\\\t+1 (403) 262-3443\\\\t+1 (403) 262-3322\\\\tnancy@chinookcorp.com\\\\n3\\\\tPeacock\\\\tJane\\\\tSales Support Agent\\\\t2\\\\t1973-08-29 00:00:00\\\\t2002-04-01 00:00:00\\\\t1111 6 Ave SW\\\\tCalgary\\\\tAB\\\\tCanada\\\\tT2P 5M5\\\\t+1 (403) 262-3443\\\\t+1 (403) 262-6712\\\\tjane@chinookcorp.com\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Genre\" (\\\\n\\\\t\"GenreId\" INTEGER NOT NULL, \\\\n\\\\t\"Name\" NVARCHAR(120), \\\\n\\\\tPRIMARY KEY (\"GenreId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Genre table:\\\\nGenreId\\\\tName\\\\n1\\\\tRock\\\\n2\\\\tJazz\\\\n3\\\\tMetal\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Invoice\" (\\\\n\\\\t\"InvoiceId\" INTEGER NOT NULL, \\\\n\\\\t\"CustomerId\" INTEGER NOT NULL, \\\\n\\\\t\"InvoiceDate\" DATETIME NOT NULL, \\\\n\\\\t\"BillingAddress\" NVARCHAR(70), \\\\n\\\\t\"BillingCity\" NVARCHAR(40), \\\\n\\\\t\"BillingState\" NVARCHAR(40), \\\\n\\\\t\"BillingCountry\" NVARCHAR(40), \\\\n\\\\t\"BillingPostalCode\" NVARCHAR(10), \\\\n\\\\t\"Total\" NUMERIC(10, 2) NOT NULL, \\\\n\\\\tPRIMARY KEY (\"InvoiceId\"), \\\\n\\\\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Invoice table:\\\\nInvoiceId\\\\tCustomerId\\\\tInvoiceDate\\\\tBillingAddress\\\\tBillingCity\\\\tBillingState\\\\tBillingCountry\\\\tBillingPostalCode\\\\tTotal\\\\n1\\\\t2\\\\t2021-01-01 00:00:00\\\\tTheodor-Heuss-Straße 34\\\\tStuttgart\\\\tNone\\\\tGermany\\\\t70174\\\\t1.98\\\\n2\\\\t4\\\\t2021-01-02 00:00:00\\\\tUllevålsveien 14\\\\tOslo\\\\tNone\\\\tNorway\\\\t0171\\\\t3.96\\\\n3\\\\t8\\\\t2021-01-03 00:00:00\\\\tGrétrystraat 63\\\\tBrussels\\\\tNone\\\\tBelgium\\\\t1000\\\\t5.94\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"InvoiceLine\" (\\\\n\\\\t\"InvoiceLineId\" INTEGER NOT NULL, \\\\n\\\\t\"InvoiceId\" INTEGER NOT NULL, \\\\n\\\\t\"TrackId\" INTEGER NOT NULL, \\\\n\\\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\\\n\\\\t\"Quantity\" INTEGER NOT NULL, \\\\n\\\\tPRIMARY KEY (\"InvoiceLineId\"), \\\\n\\\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\\\n\\\\tFOREIGN KEY(\"InvoiceId\") REFERENCES \"Invoice\" (\"InvoiceId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from InvoiceLine table:\\\\nInvoiceLineId\\\\tInvoiceId\\\\tTrackId\\\\tUnitPrice\\\\tQuantity\\\\n1\\\\t1\\\\t2\\\\t0.99\\\\t1\\\\n2\\\\t1\\\\t4\\\\t0.99\\\\t1\\\\n3\\\\t2\\\\t6\\\\t0.99\\\\t1\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"MediaType\" (\\\\n\\\\t\"MediaTypeId\" INTEGER NOT NULL, \\\\n\\\\t\"Name\" NVARCHAR(120), \\\\n\\\\tPRIMARY KEY (\"MediaTypeId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from MediaType table:\\\\nMediaTypeId\\\\tName\\\\n1\\\\tMPEG audio file\\\\n2\\\\tProtected AAC audio file\\\\n3\\\\tProtected MPEG-4 video file\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Playlist\" (\\\\n\\\\t\"PlaylistId\" INTEGER NOT NULL, \\\\n\\\\t\"Name\" NVARCHAR(120), \\\\n\\\\tPRIMARY KEY (\"PlaylistId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Playlist table:\\\\nPlaylistId\\\\tName\\\\n1\\\\tMusic\\\\n2\\\\tMovies\\\\n3\\\\tTV Shows\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"PlaylistTrack\" (\\\\n\\\\t\"PlaylistId\" INTEGER NOT NULL, \\\\n\\\\t\"TrackId\" INTEGER NOT NULL, \\\\n\\\\tPRIMARY KEY (\"PlaylistId\", \"TrackId\"), \\\\n\\\\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \\\\n\\\\tFOREIGN KEY(\"PlaylistId\") REFERENCES \"Playlist\" (\"PlaylistId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from PlaylistTrack table:\\\\nPlaylistId\\\\tTrackId\\\\n1\\\\t3402\\\\n1\\\\t3389\\\\n1\\\\t3390\\\\n*/\\\\n\\\\n\\\\nCREATE TABLE \"Track\" (\\\\n\\\\t\"TrackId\" INTEGER NOT NULL, \\\\n\\\\t\"Name\" NVARCHAR(200) NOT NULL, \\\\n\\\\t\"AlbumId\" INTEGER, \\\\n\\\\t\"MediaTypeId\" INTEGER NOT NULL, \\\\n\\\\t\"GenreId\" INTEGER, \\\\n\\\\t\"Composer\" NVARCHAR(220), \\\\n\\\\t\"Milliseconds\" INTEGER NOT NULL, \\\\n\\\\t\"Bytes\" INTEGER, \\\\n\\\\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \\\\n\\\\tPRIMARY KEY (\"TrackId\"), \\\\n\\\\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \\\\n\\\\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \\\\n\\\\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\\\\n)\\\\n\\\\n/*\\\\n3 rows from Track table:\\\\nTrackId\\\\tName\\\\tAlbumId\\\\tMediaTypeId\\\\tGenreId\\\\tComposer\\\\tMilliseconds\\\\tBytes\\\\tUnitPrice\\\\n1\\\\tFor Those About To Rock (We Salute You)\\\\t1\\\\t1\\\\t1\\\\tAngus Young, Malcolm Young, Brian Johnson\\\\t343719\\\\t11170334\\\\t0.99\\\\n2\\\\tBalls to the Wall\\\\t2\\\\t2\\\\t1\\\\tU. Dirkschneider, W. Hoffmann, H. Frank, P. Baltes, S. Kaufmann, G. Hoffmann\\\\t342562\\\\t5510424\\\\t0.99\\\\n3\\\\tFast As a Shark\\\\t3\\\\t2\\\\t1\\\\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\\\\t230619\\\\t3990994\\\\t0.99\\\\n*/\\', \\'table_names\\': \\'Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\\'}\\n',\n", - " 'output': 'The customer who has spent the most money is Helena Holý.',\n", - " 'citations': [CohereCitation(start=45, end=56, text='Helena Holý', documents=[{'output': \"[(6, 'Helena', 'Holý', 49.62)]\"}])],\n", - " 'intermediate_steps': [(AgentActionMessageLog(tool='sql_db_query', tool_input={'query': 'SELECT c.CustomerId, c.FirstName, c.LastName, SUM(i.Total) AS TotalSpent\\nFROM Customer c\\nJOIN Invoice i ON c.CustomerId = i.CustomerId\\nGROUP BY c.CustomerId\\nORDER BY TotalSpent DESC\\nLIMIT 1;'}, log=\"\\nI will write a SQL query to find the customer who has spent the most money.\\n{'tool_name': 'sql_db_query', 'parameters': {'query': 'SELECT c.CustomerId, c.FirstName, c.LastName, SUM(i.Total) AS TotalSpent\\\\nFROM Customer c\\\\nJOIN Invoice i ON c.CustomerId = i.CustomerId\\\\nGROUP BY c.CustomerId\\\\nORDER BY TotalSpent DESC\\\\nLIMIT 1;'}}\\n\", message_log=[AIMessage(content='\\nPlan: I will write a SQL query to find the customer who has spent the most money.\\nAction: ```json\\n[\\n {\\n \"tool_name\": \"sql_db_query\",\\n \"parameters\": {\\n \"query\": \"SELECT c.CustomerId, c.FirstName, c.LastName, SUM(i.Total) AS TotalSpent\\\\nFROM Customer c\\\\nJOIN Invoice i ON c.CustomerId = i.CustomerId\\\\nGROUP BY c.CustomerId\\\\nORDER BY TotalSpent DESC\\\\nLIMIT 1;\"\\n }\\n }\\n]\\n```')]),\n", - " \"[(6, 'Helena', 'Holý', 49.62)]\")]}" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "agent_executor.invoke({\n", + "output=agent_executor.invoke({\n", " \"input\": 'provide the name of the best customer? The customer who has spent the most money is the best.',\n", " \"preamble\": preamble\n", "})" ] }, { - "cell_type": "markdown", - "id": "b1cfcaaa-b1c0-4ded-baaa-7bbdb097be6e", + "cell_type": "code", + "execution_count": 27, + "id": "ff38320e-b40b-4d03-bcd2-beb40eeed655", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The customer who has spent the most money is Helena Holý.\n" + ] + } + ], "source": [ - "Great, we can see that passing that additional context actually avoids the error seen in the previous section and gets to the answer in one tool call. Of course this works as long as you have a few tables and a few columns per table. We will follow up with more techniques to improve stability and scalability in another notebook." + "print(output['output'])" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "95a1feed-1480-497d-bacf-9ab2667b573c", + "cell_type": "markdown", + "id": "b1cfcaaa-b1c0-4ded-baaa-7bbdb097be6e", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "We can see that passing that additional context actually avoids the error seen in the previous section and gets to the answer in one tool call. This works as long as you have a few tables and a few columns per table. We will follow up with more techniques to improve stability and scalability in future work." + ] } ], "metadata": { diff --git a/notebooks/guides/Analysis_of_Form_10_K_Using_Cohere_and_RAG.ipynb b/notebooks/guides/Analysis_of_Form_10_K_Using_Cohere_and_RAG.ipynb index e83eb62e..f3e4b799 100644 --- a/notebooks/guides/Analysis_of_Form_10_K_Using_Cohere_and_RAG.ipynb +++ b/notebooks/guides/Analysis_of_Form_10_K_Using_Cohere_and_RAG.ipynb @@ -1,2845 +1,2846 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "UzG0FP8fwmIZ" - }, - "source": [ - "# **Analysis of Form 10-K/10-Q Using Cohere and RAG**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "NXzl9w_9Zf5K" - }, - "source": [ - "## **Getting Started**\n", - "\n", - "You may use this script to jumpstart financial analysis of 10-Ks or 10-Qs with Cohere's Command model.\n", - "\n", - "This cookbook relies on helpful tooling from LlamaIndex, as well as our Cohere SDK. If you're familiar with LlamaIndex, it should be easy to slot this process into your own productivity flows." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "UzG0FP8fwmIZ" + }, + "source": [ + "# **Analysis of Form 10-K/10-Q Using Cohere and RAG**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NXzl9w_9Zf5K" + }, + "source": [ + "## **Getting Started**\n", + "\n", + "You may use this script to jumpstart financial analysis of 10-Ks or 10-Qs with Cohere's Command model.\n", + "\n", + "This cookbook relies on helpful tooling from LlamaIndex, as well as our Cohere SDK. If you're familiar with LlamaIndex, it should be easy to slot this process into your own productivity flows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "eYFvTs4mVpU4" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!sudo apt install tesseract-ocr poppler-utils\n", + "!pip install \"cohere<5\" langchain llama-index llama-index-embeddings-cohere llama-index-postprocessor-cohere-rerank pytesseract pdf2image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "LYmEOVKCAuk7" + }, + "outputs": [], + "source": [ + "# Due to compatibility issues, we need to do imports like this\n", + "from llama_index.core.schema import TextNode\n", + "\n", + "%%capture\n", + "!pip install unstructured" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 }, + "id": "Lc8CGMajDV9b", + "outputId": "5efe06b3-7eb5-490c-e9d3-b95b926358ed" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "eYFvTs4mVpU4" - }, - "outputs": [], - "source": [ - "%%capture\n", - "!sudo apt install tesseract-ocr poppler-utils\n", - "!pip install \"cohere<5\" langchain llama-index llama-index-embeddings-cohere llama-index-postprocessor-cohere-rerank pytesseract pdf2image" + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "LYmEOVKCAuk7" - }, - "outputs": [], - "source": [ - "# Due to compatibility issues, we need to do imports like this\n", - "from llama_index.core.schema import TextNode\n", - "\n", - "%%capture\n", - "!pip install unstructured" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter your Cohere API key: ··········\n" + ] + } + ], + "source": [ + "import cohere\n", + "from getpass import getpass\n", + "\n", + "# Set up Cohere client\n", + "COHERE_API_KEY = getpass(\"Enter your Cohere API key: \")\n", + "\n", + "# Instantiate a client to communicate with Cohere's API using our Python SDK\n", + "co = cohere.Client(COHERE_API_KEY)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FfCtNkl6Z-eP" + }, + "source": [ + "## **Step 1: Loading a 10-K**\n", + "\n", + "You may run the following cells to load a 10-K that has already been preprocessed with OCR.\n", + "\n", + "> 💡 If you'd like to run the OCR pipeline yourself, you can find more info in the section titled **PDF to Text using OCR and `pdf2image`**." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 71 }, + "id": "6gkZ67Eh7l1A", + "outputId": "84406883-d4d4-44b5-c071-837410ee0d5a" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "Lc8CGMajDV9b", - "outputId": "5efe06b3-7eb5-490c-e9d3-b95b926358ed" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter your Cohere API key: ··········\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "import cohere\n", - "from getpass import getpass\n", - "\n", - "# Set up Cohere client\n", - "COHERE_API_KEY = getpass(\"Enter your Cohere API key: \")\n", - "\n", - "# Instantiate a client to communicate with Cohere's API using our Python SDK\n", - "co = cohere.Client(COHERE_API_KEY)\n" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "FfCtNkl6Z-eP" - }, - "source": [ - "## **Step 1: Loading a 10-K**\n", - "\n", - "You may run the following cells to load a 10-K that has already been preprocessed with OCR.\n", - "\n", - "> 💡 If you'd like to run the OCR pipeline yourself, you can find more info in the section titled **PDF to Text using OCR and `pdf2image`**." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "[nltk_data] Downloading package averaged_perceptron_tagger to\n", + "[nltk_data] /root/nltk_data...\n", + "[nltk_data] Unzipping taggers/averaged_perceptron_tagger.zip.\n" + ] + } + ], + "source": [ + "# Using langchain here since they have access to the Unstructured Data Loader powered by unstructured.io\n", + "from langchain_community.document_loaders import UnstructuredURLLoader\n", + "\n", + "# Load up Airbnb's 10-K from this past fiscal year (filed in 2024)\n", + "# Feel free to fill in some other EDGAR path\n", + "url = \"https://www.sec.gov/Archives/edgar/data/1559720/000155972024000006/abnb-20231231.htm\"\n", + "loader = UnstructuredURLLoader(urls=[url], headers={\"User-Agent\": \"cohere cohere@cohere.com\"})\n", + "documents = loader.load()\n", + "\n", + "edgar_10k = documents[0].page_content\n", + "\n", + "# Load the document(s) as simple text nodes, to be passed to the tokenization processor\n", + "nodes = [TextNode(text=document.page_content, id_=f\"doc_{i}\") for i, document in enumerate(documents)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W2PStuqwPPUM" + }, + "source": [ + "We'll need to convert the text into chunks of a certain size in order for the Cohere embedding model to properly ingest them down the line.\n", + "\n", + "We choose to use LlamaIndex's `SentenceSplitter` in this case in order to get these chunks. We must pass a tokenization callable, which we can do using the `transformers` library.\n", + "\n", + "You may also apply further transformations from the LlamaIndex repo if you so choose. Take a look at the [docs](https://docs.llamaindex.ai/en/stable/understanding/loading/loading.html) for inspiration on what is possible with transformations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 552, + "referenced_widgets": [ + "e2146d738e0d4fe39af19bfb22da2584", + "8670211888514256a54240d002135917", + "88b9a3c1bc78462ea149b94d1ca08e59", + "5a94eb68326b4466b7c19ad67f8f5ba6", + "ab441cef6118450f9bfbcc29f8f34d4f", + "016a793bd7684acc9733f1e3160bd4d6", + "c8330e6698cd41868efc23be3962db7d", + "7e9939b2a8394aa3ae4dd1a90d9517ce", + "24055747d0e44bf29f80017117e332cc", + "59f4d94a1be24ef7a1366b7220a9c9de", + "6ba07312eb854ae9a88e6cfb886b65c3", + "01d81bc2d81741e6bb0a82ba78dc2b21", + "76d51ab196f54b398dcdc574968331fa", + "b9f6e9e50e224cf89b902e419dae269a", + "1271483cc9da41b28637dce1a40fa538", + "78a1cb4ec6cc4044b2149cb84f34979c", + "403ebbf8e6da4c188c42e83ee01db07b", + "f8e3c447794448529391f9660d419632", + "a7b1f4318e3242e591b15147d699c656", + "7d7dd120240043c1aec77af517bf7add", + "204957d62b7a4f7db7fa195a3d042b42", + "930d287b503b4eeeb527c6facc97ca30", + "88fc0e784a71447abbba8273f6fcdace", + "bb120e29c7fb49e4823daf66f048e95b", + "012491a19a8143f2adc1a95c5d20e488", + "a9cd4375dfd94af4ab2c004e9dbe6fa7", + "21229dbb1f414913b8ad230648ab76e9", + "d102def58f554d48890008185d17af96", + "79a852590a0444bebad62f2c679e72c6", + "c0c90d8f84b64a11a48e81ba8dec7044", + "1167e72dd2184c6ca8c670b27c73a27d", + "af93bfd421504e3eada6c8c884869e2f", + "782b11c627be41b2b67e2774ee7fcf0b", + "159f81e1ea4c40a394b6d796527c7c4a", + "96997c9c8f3a4237b1d025252c3c2358", + "28b25e6395c54e8e9494f403953065bb", + "cf03a6a84e1345aab6d2d78f9ae5f34a", + "5a15923788d74d98a70646e1e921831e", + "81d523a8f29c491aaed45a199260b414", + "56cd150b53234f53b28dec80ebeb33a8", + "21c71aa09fae458fa483d58019506d46", + "b3cb567ec4934a6d935de606af921a61", + "af63d2b1e22c40629b2fe585813a2bf4", + "87d5a00cc4a2460e836ddd22cff918dd", + "a65823cef8a648cebad7e61f012de1f1", + "6643b53bdbe74a6491a3db6ec06446e9", + "93d9e20a78774bb485ceca31d4453204", + "41b58953474f49f0915d14801fb18174", + "17e8c3567f1a4d6aaa485fd1014977ae", + "0e300e8dbea143d688b08c32883d2d29", + "2e094e1165554834a0cc19ebffe93311", + "2a9c8f7bb54e4814825bddcbb10b3482", + "5f5e73e41dae4625a98a6eee6120a7d4", + "efb2bf269c1d4ace81ff4a6fabbfb3b6", + "fc96c077774241a58d24ac42dd52df7e" + ] }, + "id": "p_1mXiVZBZu2", + "outputId": "f0146d70-4a6f-4821-ed70-11200a6efd49" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 71 - }, - "id": "6gkZ67Eh7l1A", - "outputId": "84406883-d4d4-44b5-c071-837410ee0d5a" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[nltk_data] Downloading package averaged_perceptron_tagger to\n", - "[nltk_data] /root/nltk_data...\n", - "[nltk_data] Unzipping taggers/averaged_perceptron_tagger.zip.\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Using langchain here since they have access to the Unstructured Data Loader powered by unstructured.io\n", - "from langchain_community.document_loaders import UnstructuredURLLoader\n", - "\n", - "# Load up Airbnb's 10-K from this past fiscal year (filed in 2024)\n", - "# Feel free to fill in some other EDGAR path\n", - "url = \"https://www.sec.gov/Archives/edgar/data/1559720/000155972024000006/abnb-20231231.htm\"\n", - "loader = UnstructuredURLLoader(urls=[url], headers={\"User-Agent\": \"cohere cohere@cohere.com\"})\n", - "documents = loader.load()\n", - "\n", - "edgar_10k = documents[0].page_content\n", - "\n", - "# Load the document(s) as simple text nodes, to be passed to the tokenization processor\n", - "nodes = [TextNode(text=document.page_content, id_=f\"doc_{i}\") for i, document in enumerate(documents)]" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "W2PStuqwPPUM" - }, - "source": [ - "We'll need to convert the text into chunks of a certain size in order for the Cohere embedding model to properly ingest them down the line.\n", - "\n", - "We choose to use LlamaIndex's `SentenceSplitter` in this case in order to get these chunks. We must pass a tokenization callable, which we can do using the `transformers` library.\n", - "\n", - "You may also apply further transformations from the LlamaIndex repo if you so choose. Take a look at the [docs](https://docs.llamaindex.ai/en/stable/understanding/loading/loading.html) for inspiration on what is possible with transformations." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", + "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", + "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", + "You will be able to reuse this secret in all of your notebooks.\n", + "Please note that authentication is recommended but still optional to access public models or datasets.\n", + " warnings.warn(\n" + ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 552, - "referenced_widgets": [ - "e2146d738e0d4fe39af19bfb22da2584", - "8670211888514256a54240d002135917", - "88b9a3c1bc78462ea149b94d1ca08e59", - "5a94eb68326b4466b7c19ad67f8f5ba6", - "ab441cef6118450f9bfbcc29f8f34d4f", - "016a793bd7684acc9733f1e3160bd4d6", - "c8330e6698cd41868efc23be3962db7d", - "7e9939b2a8394aa3ae4dd1a90d9517ce", - "24055747d0e44bf29f80017117e332cc", - "59f4d94a1be24ef7a1366b7220a9c9de", - "6ba07312eb854ae9a88e6cfb886b65c3", - "01d81bc2d81741e6bb0a82ba78dc2b21", - "76d51ab196f54b398dcdc574968331fa", - "b9f6e9e50e224cf89b902e419dae269a", - "1271483cc9da41b28637dce1a40fa538", - "78a1cb4ec6cc4044b2149cb84f34979c", - "403ebbf8e6da4c188c42e83ee01db07b", - "f8e3c447794448529391f9660d419632", - "a7b1f4318e3242e591b15147d699c656", - "7d7dd120240043c1aec77af517bf7add", - "204957d62b7a4f7db7fa195a3d042b42", - "930d287b503b4eeeb527c6facc97ca30", - "88fc0e784a71447abbba8273f6fcdace", - "bb120e29c7fb49e4823daf66f048e95b", - "012491a19a8143f2adc1a95c5d20e488", - "a9cd4375dfd94af4ab2c004e9dbe6fa7", - "21229dbb1f414913b8ad230648ab76e9", - "d102def58f554d48890008185d17af96", - "79a852590a0444bebad62f2c679e72c6", - "c0c90d8f84b64a11a48e81ba8dec7044", - "1167e72dd2184c6ca8c670b27c73a27d", - "af93bfd421504e3eada6c8c884869e2f", - "782b11c627be41b2b67e2774ee7fcf0b", - "159f81e1ea4c40a394b6d796527c7c4a", - "96997c9c8f3a4237b1d025252c3c2358", - "28b25e6395c54e8e9494f403953065bb", - "cf03a6a84e1345aab6d2d78f9ae5f34a", - "5a15923788d74d98a70646e1e921831e", - "81d523a8f29c491aaed45a199260b414", - "56cd150b53234f53b28dec80ebeb33a8", - "21c71aa09fae458fa483d58019506d46", - "b3cb567ec4934a6d935de606af921a61", - "af63d2b1e22c40629b2fe585813a2bf4", - "87d5a00cc4a2460e836ddd22cff918dd", - "a65823cef8a648cebad7e61f012de1f1", - "6643b53bdbe74a6491a3db6ec06446e9", - "93d9e20a78774bb485ceca31d4453204", - "41b58953474f49f0915d14801fb18174", - "17e8c3567f1a4d6aaa485fd1014977ae", - "0e300e8dbea143d688b08c32883d2d29", - "2e094e1165554834a0cc19ebffe93311", - "2a9c8f7bb54e4814825bddcbb10b3482", - "5f5e73e41dae4625a98a6eee6120a7d4", - "efb2bf269c1d4ace81ff4a6fabbfb3b6", - "fc96c077774241a58d24ac42dd52df7e" - ] - }, - "id": "p_1mXiVZBZu2", - "outputId": "f0146d70-4a6f-4821-ed70-11200a6efd49" + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e2146d738e0d4fe39af19bfb22da2584", + "version_major": 2, + "version_minor": 0 }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", - "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", - "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", - "You will be able to reuse this secret in all of your notebooks.\n", - "Please note that authentication is recommended but still optional to access public models or datasets.\n", - " warnings.warn(\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "e2146d738e0d4fe39af19bfb22da2584", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "tokenizer_config.json: 0%| | 0.00/7.92k [00:00 0 else []\n", - "\n", - "pipeline = IngestionPipeline(\n", - " transformations=[\n", - " SentenceSplitter(chunk_size=512, chunk_overlap=0, tokenizer=tokenizer_fn)\n", - " ]\n", - ")\n", - "\n", - "# Run the pipeline to transform the text\n", - "nodes = pipeline.run(nodes=nodes)" + "text/plain": [ + "tokenizer_config.json: 0%| | 0.00/7.92k [00:00\n", - " pre {\n", - " white-space: pre-wrap;\n", - " }\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from llama_index.core import Settings, VectorStoreIndex\n", - "\n", - "from llama_index.postprocessor.cohere_rerank import CohereRerank\n", - "\n", - "from llama_index.embeddings.cohere import CohereEmbedding\n", - "\n", - "# Instantiate the embedding model\n", - "embed_model = CohereEmbedding(cohere_api_key=COHERE_API_KEY)\n", - "\n", - "# Global settings\n", - "Settings.chunk_size = 512\n", - "Settings.embed_model = embed_model\n", - "\n", - "# Create the vector store\n", - "index = VectorStoreIndex(nodes)\n", - "\n", - "retriever = index.as_retriever(similarity_top_k=30) # Change to whatever top_k you want\n", - "\n", - "# Instantiate the reranker\n", - "rerank = CohereRerank(api_key=COHERE_API_KEY, top_n=15)\n", - "\n", - "# Function `retrieve` is ready, using both Cohere embeddings for similarity search as well as\n", - "retrieve = lambda query: rerank.postprocess_nodes(retriever.retrieve(query), query_str=query)" + "text/plain": [ + "configuration_cohere.py: 0%| | 0.00/7.37k [00:00\n", - " pre {\n", - " white-space: pre-wrap;\n", - " }\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "PROMPT = \"List the overall revenue numbers for 2021, 2022, and 2023 in the 10-K as bullet points, then explain the revenue growth trends.\"\n", - "\n", - "# Get queries to run against our index from the command-nightly model\n", - "r = co.chat(PROMPT, model=\"command-r\", search_queries_only=True)\n", - "if r.search_queries:\n", - " queries = [q[\"text\"] for q in r.search_queries]\n", - "else:\n", - " print(\"No queries returned by the model\")" + "text/plain": [ + "tokenizer.json: 0%| | 0.00/12.8M [00:00\n", - " pre {\n", - " white-space: pre-wrap;\n", - " }\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Convenience function for formatting documents\n", - "def format_for_cohere_client(nodes_):\n", - " return [\n", - " {\n", - " \"text\": node.node.text,\n", - " \"llamaindex_id\": node.node.id_,\n", - " }\n", - " for node\n", - " in nodes_\n", - " ]\n", - "\n", - "\n", - "documents = []\n", - "# Retrieve a set of chunks from the vector index and append them to the list of\n", - "# documents that should be included in the final RAG step\n", - "for query in queries:\n", - " ret_nodes = retrieve(query)\n", - " documents.extend(format_for_cohere_client(ret_nodes))\n", - "\n", - "# One final dedpulication step in case multiple queries return the same chunk\n", - "documents = [dict(t, id=f\"doc_{i}\") for i, t in enumerate({tuple(d.items()) for d in documents})]" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" + ] + } + ], + "source": [ + "from llama_index.core.ingestion import IngestionPipeline\n", + "from llama_index.core.node_parser import SentenceSplitter\n", + "\n", + "from transformers import AutoTokenizer\n", + "\n", + "model_id = \"CohereForAI/c4ai-command-r-v01\"\n", + "tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)\n", + "\n", + "# TODO: replace with a HF implementation so this is much faster. We'll\n", + "# presumably release it when we OS the model\n", + "tokenizer_fn = lambda x: tokenizer(x).input_ids if len(x) > 0 else []\n", + "\n", + "pipeline = IngestionPipeline(\n", + " transformations=[\n", + " SentenceSplitter(chunk_size=512, chunk_overlap=0, tokenizer=tokenizer_fn)\n", + " ]\n", + ")\n", + "\n", + "# Run the pipeline to transform the text\n", + "nodes = pipeline.run(nodes=nodes)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "573Sl4Ijfura" + }, + "source": [ + "## **Step 2: Load document into a LlamaIndex vector store**\n", + "\n", + "Loading the document into a LlamaIndex vector store will allow us to use the Cohere embedding model and rerank model to retrieve the relevant parts of the form to pass into Command." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "T3-T32hQ-cYl", + "outputId": "855d765f-8d45-4a99-ab76-0f30d8ada3e0" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "kJAlJgocRxBI" - }, - "source": [ - "## **Step 4: Make a RAG request to Command using document mode**\n", - "\n", - "Now that we have our nicely formatted chunks from the 10-K, we can pass them directly into Command using the Cohere SDK. By passing the chunks into the `documents` kwarg, we enable document mode, which will perform grounded inference on the documents you pass in.\n", - "\n", - "You can see this for yourself by inspecting the `response.citations` field to check where the model is citing from.\n", - "\n", - "You can learn more about the `chat` endpoint by checking out the API reference [here](https://docs.cohere.com/reference/chat)." + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from llama_index.core import Settings, VectorStoreIndex\n", + "\n", + "from llama_index.postprocessor.cohere_rerank import CohereRerank\n", + "\n", + "from llama_index.embeddings.cohere import CohereEmbedding\n", + "\n", + "# Instantiate the embedding model\n", + "embed_model = CohereEmbedding(cohere_api_key=COHERE_API_KEY)\n", + "\n", + "# Global settings\n", + "Settings.chunk_size = 512\n", + "Settings.embed_model = embed_model\n", + "\n", + "# Create the vector store\n", + "index = VectorStoreIndex(nodes)\n", + "\n", + "retriever = index.as_retriever(similarity_top_k=30) # Change to whatever top_k you want\n", + "\n", + "# Instantiate the reranker\n", + "rerank = CohereRerank(api_key=COHERE_API_KEY, top_n=15)\n", + "\n", + "# Function `retrieve` is ready, using both Cohere embeddings for similarity search as well as\n", + "retrieve = lambda query: rerank.postprocess_nodes(retriever.retrieve(query), query_str=query)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "19QPS8pzQicf" + }, + "source": [ + "## **Step 3: Query generation and retrieval**\n", + "\n", + "In order to do RAG, we need a query or a set of queries to actually _do_ the retrieval step. As is standard in RAG settings, we'll use Command to generate those queries for us. Then, we'll use those queries along with the LlamaIndex retriever we built earlier to retrieve the most relevant pieces of the 10-K.\n", + "\n", + "To learn more about document mode and query generation, check out [our documentation](https://docs.cohere.com/docs/retrieval-augmented-generation-rag)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "XHCPxdvrFliD", + "outputId": "85cbbe95-cb88-49ec-d4ea-f7b5a15e1816" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 267 - }, - "id": "NBfQoZcXYdFc", - "outputId": "b3a4156b-2749-4aaa-8b07-7c331388183f" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Here are the overall revenue numbers for the years 2021, 2022, and 2023 as bullet points:\n", - "- 2021: $5,992 million\n", - "- 2022: $8,399 million\n", - "- 2023: $9,917 million\n", - "\n", - "Revenue increased by 18% in 2023 compared to 2022, primarily due to a 14% increase in Nights and Experiences Booked, which reached 54.5 million. This, combined with higher average daily rates, resulted in a 16% increase in Gross Booking Value, which reached $10.0 billion. \n", - "\n", - "The revenue growth trend demonstrates sustained strong travel demand. On a constant-currency basis, revenue increased by 17% in 2023 compared to the previous year.\n", - "\n", - "Other factors influencing the company's financial performance are described outside of the revenue growth trends.\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Make a request to the model\n", - "response = co.chat(\n", - " message=PROMPT,\n", - " model=\"command-r\",\n", - " temperature=0.3,\n", - " documents=documents,\n", - " prompt_truncation=\"AUTO\"\n", - ")\n", - "\n", - "print(response.text)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "PROMPT = \"List the overall revenue numbers for 2021, 2022, and 2023 in the 10-K as bullet points, then explain the revenue growth trends.\"\n", + "\n", + "# Get queries to run against our index from the command-nightly model\n", + "r = co.chat(PROMPT, model=\"command-r\", search_queries_only=True)\n", + "if r.search_queries:\n", + " queries = [q[\"text\"] for q in r.search_queries]\n", + "else:\n", + " print(\"No queries returned by the model\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nyLVmUBART3U" + }, + "source": [ + "Now, with the queries in hand, we search against our vector index." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "k4t8s4xUX51B", + "outputId": "e739b4a6-b7b4-4870-8d45-2c921b13bcf1" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 267 - }, - "id": "LHi1PDFpWj5p", - "outputId": "1d735808-b758-4535-a419-df91225b9bfb" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Here are the overall revenue numbers for the years 2021, 2022, and 2023 as bullet points:\n", - "- 2021: $5,992 million [13]\n", - "- 2022: $8,399 million [13]\n", - "- 2023: $9,917 million [13]\n", - "\n", - "Revenue increased by 18% in 2023 [11] compared to 2022, primarily due to a 14% increase in Nights and Experiences Booked [11], which reached 54.5 million. [11] This, combined with higher average daily rates [11], resulted in a 16% increase in Gross Booking Value [11], which reached $10.0 billion. [11] \n", - "\n", - "The revenue growth trend demonstrates sustained strong travel demand. [11] On a constant-currency basis [11], revenue increased by 17% in 2023 [11] compared to the previous year.\n", - "\n", - "Other factors [8, 14] influencing the company's financial performance are described outside of the revenue growth trends. [8, 14]\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Helper function for displaying response WITH citations\n", - "def insert_citations(text: str, citations: list[dict]):\n", - " \"\"\"\n", - " A helper function to pretty print citations.\n", - " \"\"\"\n", - " offset = 0\n", - " # Process citations in the order they were provided\n", - " for citation in citations:\n", - " # Adjust start/end with offset\n", - " start, end = citation['start'] + offset, citation['end'] + offset\n", - " cited_docs = [doc[4:] for doc in citation[\"document_ids\"]]\n", - " # Shorten citations if they're too long for convenience\n", - " if len(cited_docs) > 3:\n", - " placeholder = \"[\" + \", \".join(cited_docs[:3]) + \"...]\"\n", - " else:\n", - " placeholder = \"[\" + \", \".join(cited_docs) + \"]\"\n", - " # ^ doc[4:] removes the 'doc_' prefix, and leaves the quoted document\n", - " modification = f'{text[start:end]} {placeholder}'\n", - " # Replace the cited text with its bolded version + placeholder\n", - " text = text[:start] + modification + text[end:]\n", - " # Update the offset for subsequent replacements\n", - " offset += len(modification) - (end - start)\n", - "\n", - " return text\n", - "\n", - "print(insert_citations(response.text, response.citations))" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Convenience function for formatting documents\n", + "def format_for_cohere_client(nodes_):\n", + " return [\n", + " {\n", + " \"text\": node.node.text,\n", + " \"llamaindex_id\": node.node.id_,\n", + " }\n", + " for node\n", + " in nodes_\n", + " ]\n", + "\n", + "\n", + "documents = []\n", + "# Retrieve a set of chunks from the vector index and append them to the list of\n", + "# documents that should be included in the final RAG step\n", + "for query in queries:\n", + " ret_nodes = retrieve(query)\n", + " documents.extend(format_for_cohere_client(ret_nodes))\n", + "\n", + "# One final dedpulication step in case multiple queries return the same chunk\n", + "documents = [dict(t, id=f\"doc_{i}\") for i, t in enumerate({tuple(d.items()) for d in documents})]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kJAlJgocRxBI" + }, + "source": [ + "## **Step 4: Make a RAG request to Command using document mode**\n", + "\n", + "Now that we have our nicely formatted chunks from the 10-K, we can pass them directly into Command using the Cohere SDK. By passing the chunks into the `documents` kwarg, we enable document mode, which will perform grounded inference on the documents you pass in.\n", + "\n", + "You can see this for yourself by inspecting the `response.citations` field to check where the model is citing from.\n", + "\n", + "You can learn more about the `chat` endpoint by checking out the API reference [here](https://docs.cohere.com/reference/chat)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 267 }, + "id": "NBfQoZcXYdFc", + "outputId": "b3a4156b-2749-4aaa-8b07-7c331388183f" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "aI4mJqMMKE3N" - }, - "source": [ - "# **Appendix**" + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "yOeXqm1-6vXh" - }, - "source": [ - "## PDF to Text using OCR and `pdf2image`\n", - "\n", - "This method will be required for any PDFs you have that need to be converted to text.\n", - "\n", - "**WARNING**: this process can take a long time without the proper optimizations. We have provided a snippet for your use below, but use at your own risk." - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the overall revenue numbers for the years 2021, 2022, and 2023 as bullet points:\n", + "- 2021: $5,992 million\n", + "- 2022: $8,399 million\n", + "- 2023: $9,917 million\n", + "\n", + "Revenue increased by 18% in 2023 compared to 2022, primarily due to a 14% increase in Nights and Experiences Booked, which reached 54.5 million. This, combined with higher average daily rates, resulted in a 16% increase in Gross Booking Value, which reached $10.0 billion. \n", + "\n", + "The revenue growth trend demonstrates sustained strong travel demand. On a constant-currency basis, revenue increased by 17% in 2023 compared to the previous year.\n", + "\n", + "Other factors influencing the company's financial performance are described outside of the revenue growth trends.\n" + ] + } + ], + "source": [ + "# Make a request to the model\n", + "response = co.chat(\n", + " message=PROMPT,\n", + " model=\"command-r\",\n", + " temperature=0.3,\n", + " documents=documents,\n", + " prompt_truncation=\"AUTO\"\n", + ")\n", + "\n", + "print(response.text)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 267 }, + "id": "LHi1PDFpWj5p", + "outputId": "1d735808-b758-4535-a419-df91225b9bfb" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "hv91DjU77a3Q" - }, - "source": [ - "To go from PDF to text with PyTesseract, there is an intermediary step of converting the PDF to an image first, then passing that image into the OCR package, as OCR is usually only available for images.\n", - "\n", - "To do this, we use `pdf2image`, which uses `poppler` behind the scenes to convert the PDF into a PNG. From there, we can pass the image (which is a PIL Image object) directly into the OCR tool." + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "bK8sMxiTeRTB" - }, - "outputs": [], - "source": [ - "import pytesseract\n", - "from pdf2image import convert_from_path\n", - "\n", - "# pdf2image extracts as a list of PIL.Image objects\n", - "# TODO: host this PDF somewhere\n", - "pages = convert_from_path(\"/content/uber_10k.pdf\")\n", - "\n", - "# We access the only page in this sample PDF by indexing at 0\n", - "pages = [pytesseract.image_to_string(page) for page in pages]" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Here are the overall revenue numbers for the years 2021, 2022, and 2023 as bullet points:\n", + "- 2021: $5,992 million [13]\n", + "- 2022: $8,399 million [13]\n", + "- 2023: $9,917 million [13]\n", + "\n", + "Revenue increased by 18% in 2023 [11] compared to 2022, primarily due to a 14% increase in Nights and Experiences Booked [11], which reached 54.5 million. [11] This, combined with higher average daily rates [11], resulted in a 16% increase in Gross Booking Value [11], which reached $10.0 billion. [11] \n", + "\n", + "The revenue growth trend demonstrates sustained strong travel demand. [11] On a constant-currency basis [11], revenue increased by 17% in 2023 [11] compared to the previous year.\n", + "\n", + "Other factors [8, 14] influencing the company's financial performance are described outside of the revenue growth trends. [8, 14]\n" + ] + } + ], + "source": [ + "# Helper function for displaying response WITH citations\n", + "def insert_citations(text: str, citations: list[dict]):\n", + " \"\"\"\n", + " A helper function to pretty print citations.\n", + " \"\"\"\n", + " offset = 0\n", + " # Process citations in the order they were provided\n", + " for citation in citations:\n", + " # Adjust start/end with offset\n", + " start, end = citation['start'] + offset, citation['end'] + offset\n", + " cited_docs = [doc[4:] for doc in citation[\"document_ids\"]]\n", + " # Shorten citations if they're too long for convenience\n", + " if len(cited_docs) > 3:\n", + " placeholder = \"[\" + \", \".join(cited_docs[:3]) + \"...]\"\n", + " else:\n", + " placeholder = \"[\" + \", \".join(cited_docs) + \"]\"\n", + " # ^ doc[4:] removes the 'doc_' prefix, and leaves the quoted document\n", + " modification = f'{text[start:end]} {placeholder}'\n", + " # Replace the cited text with its bolded version + placeholder\n", + " text = text[:start] + modification + text[end:]\n", + " # Update the offset for subsequent replacements\n", + " offset += len(modification) - (end - start)\n", + "\n", + " return text\n", + "\n", + "print(insert_citations(response.text, response.citations))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aI4mJqMMKE3N" + }, + "source": [ + "# **Appendix**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yOeXqm1-6vXh" + }, + "source": [ + "## PDF to Text using OCR and `pdf2image`\n", + "\n", + "This method will be required for any PDFs you have that need to be converted to text.\n", + "\n", + "**WARNING**: this process can take a long time without the proper optimizations. We have provided a snippet for your use below, but use at your own risk." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hv91DjU77a3Q" + }, + "source": [ + "To go from PDF to text with PyTesseract, there is an intermediary step of converting the PDF to an image first, then passing that image into the OCR package, as OCR is usually only available for images.\n", + "\n", + "To do this, we use `pdf2image`, which uses `poppler` behind the scenes to convert the PDF into a PNG. From there, we can pass the image (which is a PIL Image object) directly into the OCR tool." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "bK8sMxiTeRTB" + }, + "outputs": [], + "source": [ + "import pytesseract\n", + "from pdf2image import convert_from_path\n", + "\n", + "# pdf2image extracts as a list of PIL.Image objects\n", + "# TODO: host this PDF somewhere\n", + "pages = convert_from_path(\"/content/uber_10k.pdf\")\n", + "\n", + "# We access the only page in this sample PDF by indexing at 0\n", + "pages = [pytesseract.image_to_string(page) for page in pages]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7w7HyFL9iaZI" + }, + "source": [ + "## Token count / price comparison and latency" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "igUBVGF0cy0D", + "outputId": "73c4d4d5-f29c-4403-8b08-c2567c39b902" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "7w7HyFL9iaZI" - }, - "source": [ - "## Token count / price comparison and latency" + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def get_response(prompt, rag):\n", + " if rag:\n", + " # Get queries to run against our index from the command-nightly model\n", + " r = co.chat(prompt, model=\"command-r\", search_queries_only=True)\n", + " if r.search_queries:\n", + " queries = [q[\"text\"] for q in r.search_queries]\n", + " else:\n", + " print(\"No queries returned by the model\")\n", + "\n", + " documents = []\n", + " # Retrieve a set of chunks from the vector index and append them to the list of\n", + " # documents that should be included in the final RAG step\n", + " for query in queries:\n", + " ret_nodes = retrieve(query)\n", + " documents.extend(format_for_cohere_client(ret_nodes))\n", + "\n", + " # One final dedpulication step in case multiple queries return the same chunk\n", + " documents = [dict(t) for t in {tuple(d.items()) for d in documents}]\n", + "\n", + " # Make a request to the model\n", + " response = co.chat(\n", + " message=prompt,\n", + " model=\"command-r\",\n", + " temperature=0.3,\n", + " documents=documents,\n", + " prompt_truncation=\"AUTO\"\n", + " )\n", + " else:\n", + " response = co.chat(\n", + " message=prompt,\n", + " model=\"command-r\",\n", + " temperature=0.3,\n", + " )\n", + "\n", + " return response" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "lX0YByK2eIeF", + "outputId": "a29cdf89-8b88-4c37-901c-6b1ce88cfa5e" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "igUBVGF0cy0D", - "outputId": "73c4d4d5-f29c-4403-8b08-c2567c39b902" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "def get_response(prompt, rag):\n", - " if rag:\n", - " # Get queries to run against our index from the command-nightly model\n", - " r = co.chat(prompt, model=\"command-r\", search_queries_only=True)\n", - " if r.search_queries:\n", - " queries = [q[\"text\"] for q in r.search_queries]\n", - " else:\n", - " print(\"No queries returned by the model\")\n", - "\n", - " documents = []\n", - " # Retrieve a set of chunks from the vector index and append them to the list of\n", - " # documents that should be included in the final RAG step\n", - " for query in queries:\n", - " ret_nodes = retrieve(query)\n", - " documents.extend(format_for_cohere_client(ret_nodes))\n", - "\n", - " # One final dedpulication step in case multiple queries return the same chunk\n", - " documents = [dict(t) for t in {tuple(d.items()) for d in documents}]\n", - "\n", - " # Make a request to the model\n", - " response = co.chat(\n", - " message=prompt,\n", - " model=\"command-r\",\n", - " temperature=0.3,\n", - " documents=documents,\n", - " prompt_truncation=\"AUTO\"\n", - " )\n", - " else:\n", - " response = co.chat(\n", - " message=prompt,\n", - " model=\"command-r\",\n", - " temperature=0.3,\n", - " )\n", - "\n", - " return response" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "prompt_template = \"\"\"# financial form 10-K\n", + "{tenk}\n", + "\n", + "# question\n", + "{question}\"\"\"\n", + "\n", + "full_context_prompt = prompt_template.format(tenk=edgar_10k, question=PROMPT)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "_s_9t57wfRCy", + "outputId": "babf0cb3-a719-467d-ec5f-80e8477f2e40" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "lX0YByK2eIeF", - "outputId": "a29cdf89-8b88-4c37-901c-6b1ce88cfa5e" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "prompt_template = \"\"\"# financial form 10-K\n", - "{tenk}\n", - "\n", - "# question\n", - "{question}\"\"\"\n", - "\n", - "full_context_prompt = prompt_template.format(tenk=edgar_10k, question=PROMPT)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "r1 = get_response(PROMPT, rag=True)\n", + "r2 = get_response(full_context_prompt, rag=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "INxf-xvdiOgF", + "outputId": "8632e4ce-e945-44d6-ed8d-7e6a4b923348" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "_s_9t57wfRCy", - "outputId": "babf0cb3-a719-467d-ec5f-80e8477f2e40" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "r1 = get_response(PROMPT, rag=True)\n", - "r2 = get_response(full_context_prompt, rag=False)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def get_price(r):\n", + " return (r.token_count[\"prompt_tokens\"] * 0.5 / 10e6) + (r.token_count[\"response_tokens\"] * 1.5 / 10e6)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 }, + "id": "uuUUZeewiSV0", + "outputId": "991125f1-5892-4744-e919-7b46930a0272" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "INxf-xvdiOgF", - "outputId": "8632e4ce-e945-44d6-ed8d-7e6a4b923348" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "def get_price(r):\n", - " return (r.token_count[\"prompt_tokens\"] * 0.5 / 10e6) + (r.token_count[\"response_tokens\"] * 1.5 / 10e6)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "uuUUZeewiSV0", - "outputId": "991125f1-5892-4744-e919-7b46930a0272" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RAG is 93% cheaper than full context\n" - ] - } - ], - "source": [ - "rag_price = get_price(r1)\n", - "full_context_price = get_price(r2)\n", - "\n", - "print(f\"RAG is {(full_context_price - rag_price) / full_context_price:.0%} cheaper than full context\")" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "RAG is 93% cheaper than full context\n" + ] + } + ], + "source": [ + "rag_price = get_price(r1)\n", + "full_context_price = get_price(r2)\n", + "\n", + "print(f\"RAG is {(full_context_price - rag_price) / full_context_price:.0%} cheaper than full context\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 }, + "id": "8sqRqK8ekKAH", + "outputId": "4d44b64c-50cc-42f0-e2f1-c38205e42c04" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "8sqRqK8ekKAH", - "outputId": "4d44b64c-50cc-42f0-e2f1-c38205e42c04" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "14.9 s ± 1.4 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "%timeit get_response(PROMPT, rag=True)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "r9Ck-k_gCNJ1", - "outputId": "fe4cdd1a-a4ac-4e20-8c8d-a3ef05ab8bcc" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "22.7 s ± 7.43 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } + "name": "stdout", + "output_type": "stream", + "text": [ + "14.9 s ± 1.4 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%timeit get_response(PROMPT, rag=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "r9Ck-k_gCNJ1", + "outputId": "fe4cdd1a-a4ac-4e20-8c8d-a3ef05ab8bcc" + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "%timeit get_response(full_context_prompt, rag=False)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Y7sLarNgFGlV" - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "name": "python" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "012491a19a8143f2adc1a95c5d20e488": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_c0c90d8f84b64a11a48e81ba8dec7044", - "max": 7366, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_1167e72dd2184c6ca8c670b27c73a27d", - "value": 7366 - } - }, - "016a793bd7684acc9733f1e3160bd4d6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "01d81bc2d81741e6bb0a82ba78dc2b21": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_76d51ab196f54b398dcdc574968331fa", - "IPY_MODEL_b9f6e9e50e224cf89b902e419dae269a", - "IPY_MODEL_1271483cc9da41b28637dce1a40fa538" - ], - "layout": "IPY_MODEL_78a1cb4ec6cc4044b2149cb84f34979c" - } - }, - "0e300e8dbea143d688b08c32883d2d29": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "1167e72dd2184c6ca8c670b27c73a27d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "1271483cc9da41b28637dce1a40fa538": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_204957d62b7a4f7db7fa195a3d042b42", - "placeholder": "​", - "style": "IPY_MODEL_930d287b503b4eeeb527c6facc97ca30", - "value": " 43.7k/43.7k [00:00<00:00, 1.97MB/s]" - } - }, - "159f81e1ea4c40a394b6d796527c7c4a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_96997c9c8f3a4237b1d025252c3c2358", - "IPY_MODEL_28b25e6395c54e8e9494f403953065bb", - "IPY_MODEL_cf03a6a84e1345aab6d2d78f9ae5f34a" - ], - "layout": "IPY_MODEL_5a15923788d74d98a70646e1e921831e" - } - }, - "17e8c3567f1a4d6aaa485fd1014977ae": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "204957d62b7a4f7db7fa195a3d042b42": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "21229dbb1f414913b8ad230648ab76e9": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "21c71aa09fae458fa483d58019506d46": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "24055747d0e44bf29f80017117e332cc": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "28b25e6395c54e8e9494f403953065bb": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_21c71aa09fae458fa483d58019506d46", - "max": 12777406, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_b3cb567ec4934a6d935de606af921a61", - "value": 12777406 - } - }, - "2a9c8f7bb54e4814825bddcbb10b3482": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "2e094e1165554834a0cc19ebffe93311": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "403ebbf8e6da4c188c42e83ee01db07b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "41b58953474f49f0915d14801fb18174": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_efb2bf269c1d4ace81ff4a6fabbfb3b6", - "placeholder": "​", - "style": "IPY_MODEL_fc96c077774241a58d24ac42dd52df7e", - "value": " 429/429 [00:00<00:00, 20.7kB/s]" - } - }, - "56cd150b53234f53b28dec80ebeb33a8": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "59f4d94a1be24ef7a1366b7220a9c9de": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "5a15923788d74d98a70646e1e921831e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "5a94eb68326b4466b7c19ad67f8f5ba6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_59f4d94a1be24ef7a1366b7220a9c9de", - "placeholder": "​", - "style": "IPY_MODEL_6ba07312eb854ae9a88e6cfb886b65c3", - "value": " 7.92k/7.92k [00:00<00:00, 366kB/s]" - } - }, - "5f5e73e41dae4625a98a6eee6120a7d4": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "6643b53bdbe74a6491a3db6ec06446e9": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_0e300e8dbea143d688b08c32883d2d29", - "placeholder": "​", - "style": "IPY_MODEL_2e094e1165554834a0cc19ebffe93311", - "value": "special_tokens_map.json: 100%" - } - }, - "6ba07312eb854ae9a88e6cfb886b65c3": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "76d51ab196f54b398dcdc574968331fa": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_403ebbf8e6da4c188c42e83ee01db07b", - "placeholder": "​", - "style": "IPY_MODEL_f8e3c447794448529391f9660d419632", - "value": "tokenization_cohere_fast.py: 100%" - } - }, - "782b11c627be41b2b67e2774ee7fcf0b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "78a1cb4ec6cc4044b2149cb84f34979c": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "79a852590a0444bebad62f2c679e72c6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "7d7dd120240043c1aec77af517bf7add": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "7e9939b2a8394aa3ae4dd1a90d9517ce": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "81d523a8f29c491aaed45a199260b414": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8670211888514256a54240d002135917": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_016a793bd7684acc9733f1e3160bd4d6", - "placeholder": "​", - "style": "IPY_MODEL_c8330e6698cd41868efc23be3962db7d", - "value": "tokenizer_config.json: 100%" - } - }, - "87d5a00cc4a2460e836ddd22cff918dd": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "88b9a3c1bc78462ea149b94d1ca08e59": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_7e9939b2a8394aa3ae4dd1a90d9517ce", - "max": 7916, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_24055747d0e44bf29f80017117e332cc", - "value": 7916 - } - }, - "88fc0e784a71447abbba8273f6fcdace": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_bb120e29c7fb49e4823daf66f048e95b", - "IPY_MODEL_012491a19a8143f2adc1a95c5d20e488", - "IPY_MODEL_a9cd4375dfd94af4ab2c004e9dbe6fa7" - ], - "layout": "IPY_MODEL_21229dbb1f414913b8ad230648ab76e9" - } - }, - "930d287b503b4eeeb527c6facc97ca30": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "93d9e20a78774bb485ceca31d4453204": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_2a9c8f7bb54e4814825bddcbb10b3482", - "max": 429, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_5f5e73e41dae4625a98a6eee6120a7d4", - "value": 429 - } - }, - "96997c9c8f3a4237b1d025252c3c2358": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_81d523a8f29c491aaed45a199260b414", - "placeholder": "​", - "style": "IPY_MODEL_56cd150b53234f53b28dec80ebeb33a8", - "value": "tokenizer.json: 100%" - } - }, - "a65823cef8a648cebad7e61f012de1f1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_6643b53bdbe74a6491a3db6ec06446e9", - "IPY_MODEL_93d9e20a78774bb485ceca31d4453204", - "IPY_MODEL_41b58953474f49f0915d14801fb18174" - ], - "layout": "IPY_MODEL_17e8c3567f1a4d6aaa485fd1014977ae" - } - }, - "a7b1f4318e3242e591b15147d699c656": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "a9cd4375dfd94af4ab2c004e9dbe6fa7": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_af93bfd421504e3eada6c8c884869e2f", - "placeholder": "​", - "style": "IPY_MODEL_782b11c627be41b2b67e2774ee7fcf0b", - "value": " 7.37k/7.37k [00:00<00:00, 373kB/s]" - } - }, - "ab441cef6118450f9bfbcc29f8f34d4f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "af63d2b1e22c40629b2fe585813a2bf4": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "af93bfd421504e3eada6c8c884869e2f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "b3cb567ec4934a6d935de606af921a61": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "b9f6e9e50e224cf89b902e419dae269a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_a7b1f4318e3242e591b15147d699c656", - "max": 43727, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_7d7dd120240043c1aec77af517bf7add", - "value": 43727 - } - }, - "bb120e29c7fb49e4823daf66f048e95b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d102def58f554d48890008185d17af96", - "placeholder": "​", - "style": "IPY_MODEL_79a852590a0444bebad62f2c679e72c6", - "value": "configuration_cohere.py: 100%" - } - }, - "c0c90d8f84b64a11a48e81ba8dec7044": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "c8330e6698cd41868efc23be3962db7d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "cf03a6a84e1345aab6d2d78f9ae5f34a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_af63d2b1e22c40629b2fe585813a2bf4", - "placeholder": "​", - "style": "IPY_MODEL_87d5a00cc4a2460e836ddd22cff918dd", - "value": " 12.8M/12.8M [00:00<00:00, 51.7MB/s]" - } - }, - "d102def58f554d48890008185d17af96": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "e2146d738e0d4fe39af19bfb22da2584": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_8670211888514256a54240d002135917", - "IPY_MODEL_88b9a3c1bc78462ea149b94d1ca08e59", - "IPY_MODEL_5a94eb68326b4466b7c19ad67f8f5ba6" - ], - "layout": "IPY_MODEL_ab441cef6118450f9bfbcc29f8f34d4f" - } - }, - "efb2bf269c1d4ace81ff4a6fabbfb3b6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "f8e3c447794448529391f9660d419632": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "fc96c077774241a58d24ac42dd52df7e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - } - } + "name": "stdout", + "output_type": "stream", + "text": [ + "22.7 s ± 7.43 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] } + ], + "source": [ + "%timeit get_response(full_context_prompt, rag=False)" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "012491a19a8143f2adc1a95c5d20e488": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c0c90d8f84b64a11a48e81ba8dec7044", + "max": 7366, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_1167e72dd2184c6ca8c670b27c73a27d", + "value": 7366 + } + }, + "016a793bd7684acc9733f1e3160bd4d6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "01d81bc2d81741e6bb0a82ba78dc2b21": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_76d51ab196f54b398dcdc574968331fa", + "IPY_MODEL_b9f6e9e50e224cf89b902e419dae269a", + "IPY_MODEL_1271483cc9da41b28637dce1a40fa538" + ], + "layout": "IPY_MODEL_78a1cb4ec6cc4044b2149cb84f34979c" + } + }, + "0e300e8dbea143d688b08c32883d2d29": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1167e72dd2184c6ca8c670b27c73a27d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "1271483cc9da41b28637dce1a40fa538": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_204957d62b7a4f7db7fa195a3d042b42", + "placeholder": "​", + "style": "IPY_MODEL_930d287b503b4eeeb527c6facc97ca30", + "value": " 43.7k/43.7k [00:00<00:00, 1.97MB/s]" + } + }, + "159f81e1ea4c40a394b6d796527c7c4a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_96997c9c8f3a4237b1d025252c3c2358", + "IPY_MODEL_28b25e6395c54e8e9494f403953065bb", + "IPY_MODEL_cf03a6a84e1345aab6d2d78f9ae5f34a" + ], + "layout": "IPY_MODEL_5a15923788d74d98a70646e1e921831e" + } + }, + "17e8c3567f1a4d6aaa485fd1014977ae": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "204957d62b7a4f7db7fa195a3d042b42": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "21229dbb1f414913b8ad230648ab76e9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "21c71aa09fae458fa483d58019506d46": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "24055747d0e44bf29f80017117e332cc": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "28b25e6395c54e8e9494f403953065bb": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_21c71aa09fae458fa483d58019506d46", + "max": 12777406, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_b3cb567ec4934a6d935de606af921a61", + "value": 12777406 + } + }, + "2a9c8f7bb54e4814825bddcbb10b3482": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "2e094e1165554834a0cc19ebffe93311": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "403ebbf8e6da4c188c42e83ee01db07b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "41b58953474f49f0915d14801fb18174": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_efb2bf269c1d4ace81ff4a6fabbfb3b6", + "placeholder": "​", + "style": "IPY_MODEL_fc96c077774241a58d24ac42dd52df7e", + "value": " 429/429 [00:00<00:00, 20.7kB/s]" + } + }, + "56cd150b53234f53b28dec80ebeb33a8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "59f4d94a1be24ef7a1366b7220a9c9de": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5a15923788d74d98a70646e1e921831e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5a94eb68326b4466b7c19ad67f8f5ba6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_59f4d94a1be24ef7a1366b7220a9c9de", + "placeholder": "​", + "style": "IPY_MODEL_6ba07312eb854ae9a88e6cfb886b65c3", + "value": " 7.92k/7.92k [00:00<00:00, 366kB/s]" + } + }, + "5f5e73e41dae4625a98a6eee6120a7d4": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "6643b53bdbe74a6491a3db6ec06446e9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_0e300e8dbea143d688b08c32883d2d29", + "placeholder": "​", + "style": "IPY_MODEL_2e094e1165554834a0cc19ebffe93311", + "value": "special_tokens_map.json: 100%" + } + }, + "6ba07312eb854ae9a88e6cfb886b65c3": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "76d51ab196f54b398dcdc574968331fa": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_403ebbf8e6da4c188c42e83ee01db07b", + "placeholder": "​", + "style": "IPY_MODEL_f8e3c447794448529391f9660d419632", + "value": "tokenization_cohere_fast.py: 100%" + } + }, + "782b11c627be41b2b67e2774ee7fcf0b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "78a1cb4ec6cc4044b2149cb84f34979c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "79a852590a0444bebad62f2c679e72c6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "7d7dd120240043c1aec77af517bf7add": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "7e9939b2a8394aa3ae4dd1a90d9517ce": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "81d523a8f29c491aaed45a199260b414": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8670211888514256a54240d002135917": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_016a793bd7684acc9733f1e3160bd4d6", + "placeholder": "​", + "style": "IPY_MODEL_c8330e6698cd41868efc23be3962db7d", + "value": "tokenizer_config.json: 100%" + } + }, + "87d5a00cc4a2460e836ddd22cff918dd": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "88b9a3c1bc78462ea149b94d1ca08e59": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7e9939b2a8394aa3ae4dd1a90d9517ce", + "max": 7916, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_24055747d0e44bf29f80017117e332cc", + "value": 7916 + } + }, + "88fc0e784a71447abbba8273f6fcdace": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_bb120e29c7fb49e4823daf66f048e95b", + "IPY_MODEL_012491a19a8143f2adc1a95c5d20e488", + "IPY_MODEL_a9cd4375dfd94af4ab2c004e9dbe6fa7" + ], + "layout": "IPY_MODEL_21229dbb1f414913b8ad230648ab76e9" + } + }, + "930d287b503b4eeeb527c6facc97ca30": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "93d9e20a78774bb485ceca31d4453204": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_2a9c8f7bb54e4814825bddcbb10b3482", + "max": 429, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5f5e73e41dae4625a98a6eee6120a7d4", + "value": 429 + } + }, + "96997c9c8f3a4237b1d025252c3c2358": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_81d523a8f29c491aaed45a199260b414", + "placeholder": "​", + "style": "IPY_MODEL_56cd150b53234f53b28dec80ebeb33a8", + "value": "tokenizer.json: 100%" + } + }, + "a65823cef8a648cebad7e61f012de1f1": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_6643b53bdbe74a6491a3db6ec06446e9", + "IPY_MODEL_93d9e20a78774bb485ceca31d4453204", + "IPY_MODEL_41b58953474f49f0915d14801fb18174" + ], + "layout": "IPY_MODEL_17e8c3567f1a4d6aaa485fd1014977ae" + } + }, + "a7b1f4318e3242e591b15147d699c656": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a9cd4375dfd94af4ab2c004e9dbe6fa7": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_af93bfd421504e3eada6c8c884869e2f", + "placeholder": "​", + "style": "IPY_MODEL_782b11c627be41b2b67e2774ee7fcf0b", + "value": " 7.37k/7.37k [00:00<00:00, 373kB/s]" + } + }, + "ab441cef6118450f9bfbcc29f8f34d4f": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "af63d2b1e22c40629b2fe585813a2bf4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "af93bfd421504e3eada6c8c884869e2f": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b3cb567ec4934a6d935de606af921a61": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "b9f6e9e50e224cf89b902e419dae269a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a7b1f4318e3242e591b15147d699c656", + "max": 43727, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7d7dd120240043c1aec77af517bf7add", + "value": 43727 + } + }, + "bb120e29c7fb49e4823daf66f048e95b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d102def58f554d48890008185d17af96", + "placeholder": "​", + "style": "IPY_MODEL_79a852590a0444bebad62f2c679e72c6", + "value": "configuration_cohere.py: 100%" + } + }, + "c0c90d8f84b64a11a48e81ba8dec7044": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c8330e6698cd41868efc23be3962db7d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "cf03a6a84e1345aab6d2d78f9ae5f34a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_af63d2b1e22c40629b2fe585813a2bf4", + "placeholder": "​", + "style": "IPY_MODEL_87d5a00cc4a2460e836ddd22cff918dd", + "value": " 12.8M/12.8M [00:00<00:00, 51.7MB/s]" + } + }, + "d102def58f554d48890008185d17af96": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "e2146d738e0d4fe39af19bfb22da2584": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_8670211888514256a54240d002135917", + "IPY_MODEL_88b9a3c1bc78462ea149b94d1ca08e59", + "IPY_MODEL_5a94eb68326b4466b7c19ad67f8f5ba6" + ], + "layout": "IPY_MODEL_ab441cef6118450f9bfbcc29f8f34d4f" + } + }, + "efb2bf269c1d4ace81ff4a6fabbfb3b6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "f8e3c447794448529391f9660d419632": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "fc96c077774241a58d24ac42dd52df7e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/guides/Basic_Semantic_Search.ipynb b/notebooks/guides/Basic_Semantic_Search.ipynb index 681311e9..37deac0d 100644 --- a/notebooks/guides/Basic_Semantic_Search.ipynb +++ b/notebooks/guides/Basic_Semantic_Search.ipynb @@ -1,7 +1,6 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "65_Qg86Sl2eF" @@ -36,12 +35,10 @@ "source": [ "# Install Cohere for embeddings, Umap to reduce embeddings to 2 dimensions, \n", "# Altair for visualization, Annoy for approximate nearest neighbor search\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" umap-learn altair annoy datasets tqdm" + "# TODO: upgrade to \"cohere>5\"!pip install \"cohere<5\" umap-learn altair annoy datasets tqdm" ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -70,7 +67,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 1. Getting Set up" + "## 1. Getting Set Up" ] }, { @@ -99,7 +96,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -124,7 +120,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "2LZ7SBKSU4bx" @@ -359,7 +354,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "zrajiGkNVw7E" @@ -370,7 +364,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -427,7 +420,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "lzcDFCDePVxA" @@ -474,7 +466,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "GfIDv25K0A-0" @@ -613,7 +604,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "bI4kGnnPcu90" @@ -776,7 +766,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "4tN7fGDst7rh" @@ -892,7 +881,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "id": "4ZEYkKsSfQne" @@ -905,12 +893,6 @@ "\n", "We can’t wait to see what you start building! Share your projects or find support on [Discord](https://discord.com/invite/co-mmunity).\n" ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [] } ], "metadata": { @@ -934,7 +916,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.8.16" }, "widgets": { "application/vnd.jupyter.widget-state+json": { diff --git a/notebooks/guides/Basic_Summarization_Notebook.ipynb b/notebooks/guides/Basic_Summarization_Notebook.ipynb index 87d3b645..7cbad4cd 100644 --- a/notebooks/guides/Basic_Summarization_Notebook.ipynb +++ b/notebooks/guides/Basic_Summarization_Notebook.ipynb @@ -16,23 +16,6 @@ "`\"\". In summary: \"\"`." ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "EqdDiovEBRLw", - "outputId": "b72dc9ea-d73f-4291-bc59-7d3b1d8490cd" - }, - "outputs": [], - "source": [ - "# Let's first install Cohere's python SDK\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\"" - ] - }, { "cell_type": "code", "execution_count": 1, @@ -256,18 +239,11 @@ "id": "M3HM7go_tebY" }, "source": [ - "In a lot of cases, better generations can be reached by creating multiple generations then ranking and filtering them. In this case we're ranking the generations by their average likelihoods. \n", + "In a lot of cases, better generations can be reached by creating multiple generations then ranking and filtering them. In this case, we're ranking the generations by their average likelihoods. \n", "\n", "## Hyperparameters\n", "It's worth spending some time learning the various hyperparameters of the generation endpoint. For example, [temperature](https://docs.cohere.ai/temperature-wiki) tunes the degree of randomness in the generations. Other parameters include [top-k and top-p](https://docs.cohere.ai/token-picking) as well as `frequency_penalty` and `presence_penalty` which can reduce the amount of repetition in the output of the model. See the [API reference of the generate endpoint](https://docs.cohere.ai/generate-reference) for more details on all the parameters." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -291,7 +267,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/guides/Chunking_strategies.ipynb b/notebooks/guides/Chunking_strategies.ipynb index 26ce93e6..41e7487e 100644 --- a/notebooks/guides/Chunking_strategies.ipynb +++ b/notebooks/guides/Chunking_strategies.ipynb @@ -1,17 +1,8 @@ { "cells": [ - { - "cell_type": "markdown", - "source": [ - "*![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)*" - ], - "metadata": { - "id": "KA0rmEN-XNsd" - } - }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "id": "F_jICWZXSVA8" }, @@ -52,12 +43,7 @@ }, { "cell_type": "code", - "source": [ - "# Set up Cohere client\n", - "co_model = 'command-r'\n", - "co_api_key = getpass(\"Enter Cohere API key: \")\n", - "co = cohere.Client(api_key=co_api_key)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -65,7 +51,6 @@ "id": "wznWW57-BAML", "outputId": "56de0fa7-7321-4718-8133-8740d405e78b" }, - "execution_count": null, "outputs": [ { "name": "stdout", @@ -74,39 +59,47 @@ "Enter Cohere API key: ··········\n" ] } + ], + "source": [ + "# Set up Cohere client\n", + "co_model = 'command-r'\n", + "co_api_key = getpass(\"Enter Cohere API key: \")\n", + "co = cohere.Client(api_key=co_api_key)" ] }, { "cell_type": "markdown", + "metadata": { + "id": "pIJH7u4dL7mZ" + }, "source": [ - "\n", - "# Introduction\n", + "## Introduction\n", "\n", "Chunking is an essential component of any RAG-based system. This cookbook aims to demonstrate how different chunking strategies affect the results of LLM-generated output. There are multiple considerations that need to be taken into account when designing chunking strategy. Therefore, we begin by providing a framework for these strategies and then jump into a practical example. We will focus our example on transcript calls, which create a unique challenge because of their rich content and the change of people speaking throughout the text.\n", "\n", - "# Table of content\n", + "## Table of contents\n", "\n", - "1. [Chunking Strategies Framework](#framework)\n", + "1. [Chunking strategies framework](#chunking-strategies-framework)\n", "2. [Getting started](#getting-started)\n", "3. [Example 1: Chunking using content-independent strategies](#example-1)\n", "4. [Example 2: Chunking using content-dependent strategies](#example-2)\n", "5. [Discussion](#discussion)" - ], - "metadata": { - "id": "pIJH7u4dL7mZ" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "Yuse4PR_9saD" + }, "source": [ - "\n", - "# Chunking Strategies Framework\n", + "\n", + "## Chunking strategies framework\n", "\n", - "## Document splitting\n", + "### Document splitting\n", "\n", "By document splitting, we mean deciding on the conditions under which we will break the text. At this stage, we should ask, *\"Are there any parts of consecutive text we want to ensure we do not break?\"*. If the answer is \"no\", then, the content-independent splitting strategies are helpful. On the other hand, in scenarios like transcripts or meeting notes, we probably would like to keep the content of one speaker together, which might require us to deploy content-dependent strategies.\n", "\n", - "### Content-independent splitting strategies\n", + "#### Content-independent splitting strategies\n", "\n", "We split the document based on some content-independent conditions, among the most popular ones are:\n", "- splitting by the number of characters,\n", @@ -115,49 +108,41 @@ "\n", "The advantage of this scenario is that we do not need to make any assumptions about the text. However, some considerations remain, like whether we want to preserve some semantic structure, for example, sentences or paragraphs. Sentence splitting is better suited if we are looking for small chunks to ensure accuracy. Conversely, paragraphs preserve more context and might be more useful in open-ended questions.\n", "\n", - "### Content-dependent splitting strategies\n", + "#### Content-dependent splitting strategies\n", "\n", "On the other hand, there are scenarios in which we care about preserving some text structure. Then, we develop custom splitting strategies based on the document's content. A prime example is call transcripts. In such scenarios, we aim to ensure that one person's speech is fully contained within a chunk.\n", "\n", - "## Creating chunks from the document splits\n", + "### Creating chunks from the document splits\n", "\n", "After the document is split, we need to decide on the desired **size** of our chunks (the split only defines how we break the document, but we can create bigger chunks from multiple splits).\n", "\n", "Smaller chunks support more accurate retrieval. However, they might lack context. On the other hand, larger chunks offer more context, but they reduce the effectiveness of the retrieval. It is important to experiment with different settings to find the optimal balance.\n", "\n", - "## Overlapping chunks\n", + "### Overlapping chunks\n", "\n", "Overlapping chunks is a useful technique to have in the toolbox. Especially when we employ content-independent splitting strategies, it helps us mitigate some of the pitfalls of breaking the document without fully understanding the text. Overlapping guarantees that there is always some buffer between the chunks, and even if an important piece of information might be split in the original splitting strategy, it is more probable that the full information will be captured in the next chunk. The disadvantage of this method is that it creates redundancy." - ], - "metadata": { - "id": "Yuse4PR_9saD" - } + ] }, { "cell_type": "markdown", - "source": [ - "\n", - "# Getting started\n", - "\n", - "Designing a robust chunking strategy is as much a science as an art. There are no straightforward answers; the most effective strategies often emerge through experimentation. Therefore, let's dive straight into an example to illustrate this concept.\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], "metadata": { "id": "eKdDiizv_QtR" - } + }, + "source": [ + "\n", + "## Getting started\n", + "\n", + "Designing a robust chunking strategy is as much a science as an art. There are no straightforward answers; the most effective strategies often emerge through experimentation. Therefore, let's dive straight into an example to illustrate this concept." + ] }, { "cell_type": "markdown", - "source": [ - "## Utils" - ], "metadata": { "id": "1ivVb-oMCAaz" - } + }, + "source": [ + "## Utils" + ] }, { "cell_type": "code", @@ -172,11 +157,7 @@ }, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -217,11 +202,7 @@ }, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -255,7 +240,7 @@ "\n", " return text\n", "\n", - "def build_retreiver(documents, top_n=5):\n", + "def build_retriever(documents, top_n=5):\n", " # Create the embedding model\n", " embed_model = CohereEmbedding(\n", " cohere_api_key=co_api_key,\n", @@ -279,31 +264,18 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "AUXfWr13CyFE" + }, "source": [ - "##Load the data\n", + "## Load the data\n", "\n", "In this example we will work with an 2023 Tesla earning call transcript." - ], - "metadata": { - "id": "AUXfWr13CyFE" - } + ] }, { "cell_type": "code", - "source": [ - "# Get all investement memos (19) in bvp repository\n", - "url_path = 'https://www.fool.com/earnings/call-transcripts/2024/01/24/tesla-tsla-q4-2023-earnings-call-transcript/'\n", - "response = requests.get(url_path)\n", - "soup = BeautifulSoup(response.content, 'html.parser')\n", - "\n", - "target_divs = soup.find(\"div\", {\"class\": \"article-body\"}).find_all(\"p\")[2:]\n", - "print('Length of the script: ', len(target_divs))\n", - "\n", - "print()\n", - "print('Example of processed text:')\n", - "text = '\\n\\n'.join([div.get_text() for div in target_divs])\n", - "print(text[:500])" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -312,14 +284,9 @@ "id": "NeSVXvO_e1DH", "outputId": "5042cbef-d3e7-4a78-b921-aa269e60570e" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Length of the script: 385\n", "\n", @@ -346,15 +317,32 @@ "During this call, we will discuss our business outlook and make forward-looking statements. These comments are based on our predictions and \n" ] } + ], + "source": [ + "# Get all investement memos (19) in bvp repository\n", + "url_path = 'https://www.fool.com/earnings/call-transcripts/2024/01/24/tesla-tsla-q4-2023-earnings-call-transcript/'\n", + "response = requests.get(url_path)\n", + "soup = BeautifulSoup(response.content, 'html.parser')\n", + "\n", + "target_divs = soup.find(\"div\", {\"class\": \"article-body\"}).find_all(\"p\")[2:]\n", + "print('Length of the script: ', len(target_divs))\n", + "\n", + "print()\n", + "print('Example of processed text:')\n", + "text = '\\n\\n'.join([div.get_text() for div in target_divs])\n", + "print(text[:500])" ] }, { "cell_type": "markdown", + "metadata": { + "id": "UhlsdHPmhoMT" + }, "source": [ - "\n", - "# Example 1: Chunking using content-independent strategies\n", + "\n", + "## Example 1: Chunking using content-independent strategies\n", "\n", - "Let's begin with a simple content-independent strategy. We aim to answer the question, `Who mentiones Jonathan Nolan?`. We chose this question as it is easily verifiable and it requires to identify the speaker. The answer to this questions can be found in the dowloaded transcscript, here is the relevant passage:\n", + "Let's begin with a simple content-independent strategy. We aim to answer the question, `Who mentions Jonathan Nolan?`. We chose this question as it is easily verifiable and it requires to identify the speaker. The answer to this question can be found in the downloaded transcript, here is the relevant passage:\n", "\n", "\n", "```\n", @@ -362,17 +350,11 @@ "\n", "Yeah. The creators of Westworld, Jonathan Nolan, Lisa Joy Nolan, are friends -- are all friends of mine, actually. And I invited them to come see the lab and, like, well, come see it, hopefully soon. It's pretty well -- especially the sort of subsystem test stands where you've just got like one leg on a test stand just doing repetitive exercises and one arm on a test stand pretty well.\n", "```" - ], - "metadata": { - "id": "UhlsdHPmhoMT" - } + ] }, { "cell_type": "code", - "source": [ - "# Define the question\n", - "question = \"Who mentiones Jonathan Nolan?\"" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -381,14 +363,9 @@ "id": "P4xy_imcEj10", "outputId": "a2904832-788a-41d8-ae10-c9049677547c" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "# Define the question\n", + "question = \"Who mentions Jonathan Nolan?\"" ] }, { "cell_type": "markdown", + "metadata": { + "id": "cy8IXqA4H2ET" + }, "source": [ "In this case, we are more concerned about accuracy than a verbose answer, so we **focus on keeping the chunks small**. To ensure that the desired size is not exceeded, we will randomly split the list of characters, in our case `[\"\\n\\n\", \"\\n\", \" \", \"\"]`.\n", "\n", "We employ the `RecursiveCharacterTextSplitter` from [LangChain](https://python.langchain.com/docs/get_started/introduction) for this task." - ], - "metadata": { - "id": "cy8IXqA4H2ET" - } + ] }, { "cell_type": "code", - "source": [ - "# Define the chunking function\n", - "def get_chunks(text, chunk_size, chunk_overlap):\n", - " text_splitter = RecursiveCharacterTextSplitter(\n", - " chunk_size=chunk_size,\n", - " chunk_overlap=chunk_overlap,\n", - " length_function=len,\n", - " is_separator_regex=False,\n", - " )\n", - "\n", - " documents = text_splitter.create_documents([text])\n", - " documents = [Document(text=doc.page_content) for doc in documents]\n", - "\n", - " return documents" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -439,14 +410,9 @@ "id": "xy69i0i7xIy1", "outputId": "08c4a509-bab3-4f9b-9c98-cb2ad71ee59b" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "# Define the chunking function\n", + "def get_chunks(text, chunk_size, chunk_overlap):\n", + " text_splitter = RecursiveCharacterTextSplitter(\n", + " chunk_size=chunk_size,\n", + " chunk_overlap=chunk_overlap,\n", + " length_function=len,\n", + " is_separator_regex=False,\n", + " )\n", + "\n", + " documents = text_splitter.create_documents([text])\n", + " documents = [Document(text=doc.page_content) for doc in documents]\n", + "\n", + " return documents" ] }, { "cell_type": "markdown", + "metadata": { + "id": "4YXsoVMMGCnC" + }, "source": [ "### Experiment 1 - no overlap\n", "In our first experiment we define the chunk size as 500 and allow **no overlap between consecutive chunks**.\n", "\n", "Subsequently, we implement the standard RAG pipeline. We feed the chunks into a retriever, selecting the `top_n` most pertinent to the query chunks, and supply them as context to the generation model. Throughout this pipeline, we leverage [Cohere's endpoints](https://docs.cohere.com/reference/about), specifically, `co.embed`, `co.re.rank`, and finally, `co.chat`." - ], - "metadata": { - "id": "4YXsoVMMGCnC" - } + ] }, { "cell_type": "code", - "source": [ - "chunk_size = 500\n", - "chunk_overlap = 0\n", - "documents = get_chunks(text, chunk_size, chunk_overlap)\n", - "retriever = build_retreiver(documents)\n", - "\n", - "source_nodes = retriever.retrieve(question)\n", - "print('Number of docuemnts: ',len(source_nodes))\n", - "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", - "\n", - "\n", - "response = co.chat(\n", - " message=question,\n", - " documents=source_nodes,\n", - " model=co_model\n", - ")\n", - "response = response\n", - "print(response.text)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -502,14 +469,9 @@ "id": "HAG0ybf8xbcB", "outputId": "6a5f2b54-f4aa-4674-8684-7601d47bcd10" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Number of docuemnts: 5\n", "An unknown speaker mentions Jonathan Nolan in a conversation about the creators of Westworld. They mention that Jonathan Nolan and Lisa Joy Nolan are friends of theirs, and that they have invited them to visit the lab.\n" ] } + ], + "source": [ + "chunk_size = 500\n", + "chunk_overlap = 0\n", + "documents = get_chunks(text, chunk_size, chunk_overlap)\n", + "retriever = build_retriever(documents)\n", + "\n", + "source_nodes = retriever.retrieve(question)\n", + "print('Number of docuemnts: ',len(source_nodes))\n", + "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", + "\n", + "\n", + "response = co.chat(\n", + " message=question,\n", + " documents=source_nodes,\n", + " model=co_model\n", + ")\n", + "response = response\n", + "print(response.text)" ] }, { "cell_type": "markdown", - "source": [ - "A notable feature of [`co.chat`](https://docs.cohere.com/reference/chat) is its ability to ground the model's answer within the context. This means we can identify which chunks were used to generate the answer. Below, we show the previous output of the model together with the citation reference, where `[num]` represents the index of the chunk." - ], "metadata": { "id": "zbXfrN125I-i" - } + }, + "source": [ + "A notable feature of [`co.chat`](https://docs.cohere.com/reference/chat) is its ability to ground the model's answer within the context. This means we can identify which chunks were used to generate the answer. Below, we show the previous output of the model together with the citation reference, where `[num]` represents the index of the chunk." + ] }, { "cell_type": "code", - "source": [ - "print(insert_citations(response.text, response.citations))" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -554,14 +537,9 @@ "id": "pyLy-OwBGcut", "outputId": "0e4a63b0-2cf2-4021-8cb7-4292a7813644" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "An unknown speaker [0] mentions Jonathan Nolan in a conversation about the creators of Westworld. [0] They mention that Jonathan Nolan and Lisa Joy Nolan [0] are friends [0] of theirs, and that they have invited them to visit the lab. [0]\n" ] } + ], + "source": [ + "print(insert_citations(response.text, response.citations))" ] }, { "cell_type": "markdown", - "source": [ - "Indeed, by printing the cited chunk, we can validate that the text was divided so that the generation model could not provide the correct response. Notably, the speaker's name is not included in the context, which is why the model refes to an `unknown speaker`." - ], "metadata": { "id": "X07wAmqLG3Mf" - } + }, + "source": [ + "Indeed, by printing the cited chunk, we can validate that the text was divided so that the generation model could not provide the correct response. Notably, the speaker's name is not included in the context, which is why the model refes to an `unknown speaker`." + ] }, { "cell_type": "code", - "source": [ - "print(source_nodes[0])" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -605,14 +588,9 @@ "id": "StbIRRQWGei3", "outputId": "856b8735-661a-4bdb-e859-67082a56f6af" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "{'text': \"Yeah. The creators of Westworld, Jonathan Nolan, Lisa Joy Nolan, are friends -- are all friends of mine, actually. And I invited them to come see the lab and, like, well, come see it, hopefully soon. It's pretty well -- especially the sort of subsystem test stands where you've just got like one leg on a test stand just doing repetitive exercises and one arm on a test stand pretty well.\\n\\nYeah.\\n\\nUnknown speaker\\n\\nWe're not entering Westworld anytime soon.\"}\n" ] } + ], + "source": [ + "print(source_nodes[0])" ] }, { "cell_type": "markdown", + "metadata": { + "id": "Iu91q_IhHZoh" + }, "source": [ "### Experiment 2 - allow overlap\n", "In the previous experiment, we discovered that the chunks were generated in a way that made it impossible to generate the correct answer. The name of the speaker was not included in the relevant chunk.\n", "\n", "Therefore, this time to mitigate this issue, we **allow for overlap between consecutive chunks**." - ], - "metadata": { - "id": "Iu91q_IhHZoh" - } + ] }, { "cell_type": "code", - "source": [ - "chunk_size = 500\n", - "chunk_overlap = 100\n", - "documents = get_chunks(text,chunk_size, chunk_overlap)\n", - "retriever = build_retreiver(documents)\n", - "\n", - "source_nodes = retriever.retrieve(question)\n", - "print('Number of docuemnts: ',len(source_nodes))\n", - "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", - "\n", - "\n", - "response = co.chat(\n", - " message=question,\n", - " documents=source_nodes,\n", - " model=co_model\n", - ")\n", - "response = response\n", - "print(response.text)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -675,14 +642,9 @@ "id": "Za9HW8z_xog_", "outputId": "f3722475-44f2-40b1-c3d7-07cf603b4994" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Number of docuemnts: 5\n", "Elon Musk mentions Jonathan Nolan. Musk is the CEO and Product Architect of the lab that resembles the set of Westworld, a show created by Jonathan Nolan and Lisa Joy Nolan.\n" ] } + ], + "source": [ + "chunk_size = 500\n", + "chunk_overlap = 100\n", + "documents = get_chunks(text,chunk_size, chunk_overlap)\n", + "retriever = build_retriever(documents)\n", + "\n", + "source_nodes = retriever.retrieve(question)\n", + "print('Number of docuemnts: ',len(source_nodes))\n", + "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", + "\n", + "\n", + "response = co.chat(\n", + " message=question,\n", + " documents=source_nodes,\n", + " model=co_model\n", + ")\n", + "response = response\n", + "print(response.text)" ] }, { "cell_type": "markdown", - "source": [ - "Again, we can print the text along with the citations." - ], "metadata": { "id": "G1Ia5b-q5UKg" - } + }, + "source": [ + "Again, we can print the text along with the citations." + ] }, { "cell_type": "code", - "source": [ - "print(insert_citations(response.text, response.citations))" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -727,14 +710,9 @@ "id": "yluOCX4I9WcV", "outputId": "c5bb53b7-8029-4f4c-b48c-fc2d5f4df466" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Elon Musk [0] mentions Jonathan Nolan. Musk is the CEO and Product Architect [0] of the lab [0] that resembles the set of Westworld [0], a show created by Jonathan Nolan [0] and Lisa Joy Nolan. [0]\n" ] } + ], + "source": [ + "print(insert_citations(response.text, response.citations))" ] }, { "cell_type": "markdown", + "metadata": { + "id": "pMleTdDCH22o" + }, "source": [ "And investigate the chunks which were used as context to answer the query.\n", "\n" - ], - "metadata": { - "id": "pMleTdDCH22o" - } + ] }, { "cell_type": "code", - "source": [ - "source_nodes[0]" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -779,14 +762,9 @@ "id": "WdQP7ghK4GLx", "outputId": "ab3bd918-5c7b-4411-da3a-654b87b8fa0c" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "execute_result", "data": { "text/plain": [ "{'text': \"Yeah, not the best reference.\\n\\nElon Musk -- Chief Executive Officer and Product Architect\\n\\nYeah. The creators of Westworld, Jonathan Nolan, Lisa Joy Nolan, are friends -- are all friends of mine, actually. And I invited them to come see the lab and, like, well, come see it, hopefully soon. It's pretty well -- especially the sort of subsystem test stands where you've just got like one leg on a test stand just doing repetitive exercises and one arm on a test stand pretty well.\\n\\nYeah.\"}" ] }, + "execution_count": 14, "metadata": {}, - "execution_count": 14 + "output_type": "execute_result" } + ], + "source": [ + "source_nodes[0]" ] }, { "cell_type": "markdown", - "source": [ - "As we can see, by allowing overlap we managed to get the correct answer to our question." - ], "metadata": { "id": "ppL1npzNLSpQ" - } + }, + "source": [ + "As we can see, by allowing overlap we managed to get the correct answer to our question." + ] }, { "cell_type": "markdown", + "metadata": { + "id": "1IaTId1GzwMQ" + }, "source": [ - "\n", - "# Example 2: Chunking using content-dependent strategies\n", + "\n", + "## Example 2: Chunking using content-dependent strategies\n", "\n", "In the previous experiment, we provided an example of how using or not using overlapping can affect a model's performance, particularly in documents such as call transcripts where subjects change frequently. Ensuring that each chunk contains all relevant information is crucial. While we managed to retrieve the correct information by introducing overlapping into the chunking strategy, this might still not be the optimal approach for transcripts with longer speaker speeches.\n", "\n", "Therefore, in this experiment, we will adopt a content-dependent strategy.\n", "\n", "Our proposed approach entails segmenting the text whenever a new speaker begins speaking, which requires preprocessing the text accordingly." - ], - "metadata": { - "id": "1IaTId1GzwMQ" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "RqRTHKg204yV" + }, "source": [ "### Preprocess the text\n", "\n", "Firstly, let's observe that in the HTML text, each time the speaker changes, their name is enclosed within `

Name

` tags, denoting the speaker's name in bold letters.\n", "\n", "To facilitate our text chunking process, we'll use the above observation and introduce a unique character sequence `###`, which we'll utilize as a marker for splitting the text." - ], - "metadata": { - "id": "RqRTHKg204yV" - } + ] }, { "cell_type": "code", - "source": [ - "print('HTML text')\n", - "print(target_divs[:3])\n", - "print('-------------------\\n')\n", - "\n", - "text_custom = []\n", - "for div in target_divs:\n", - " if div.get_text() is None:\n", - " continue\n", - " if str(div).startswith('

'):\n", - " text_custom.append(f'### {div.get_text()}')\n", - " else:\n", - " text_custom.append(div.get_text())\n", - "\n", - "text_custom = '\\n'.join(text_custom)\n", - "print(text_custom[:500])" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -876,14 +845,9 @@ "id": "nWG44cFCzvwI", "outputId": "fc03be90-81d8-4992-9784-aac124ff33ed" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "HTML text\n", "[

Martin Viecha

,

Good afternoon, everyone, and welcome to Tesla's fourth-quarter 2023 Q&A webcast. My name is Martin Viecha, VP of investor relations, and I'm joined today by Elon Musk, Vaibhav Taneja, and a number of other executives. Our Q4 results were announced at about 3 p.m. Central Time in the update that we published at the same link as this webcast.

,

During this call, we will discuss our business outlook and make forward-looking statements. These comments are based on our predictions and expectations as of today. Actual events or results could differ materially due to a number of risks and uncertainties, including those mentioned in our most recent filings with the SEC. [Operator instructions] But before we jump into Q&A, Elon has some opening remarks.

]\n", @@ -909,49 +877,37 @@ "During this call, we will discuss our business outlook and make forward-looking statements. These comments are based on our predictions an\n" ] } + ], + "source": [ + "print('HTML text')\n", + "print(target_divs[:3])\n", + "print('-------------------\\n')\n", + "\n", + "text_custom = []\n", + "for div in target_divs:\n", + " if div.get_text() is None:\n", + " continue\n", + " if str(div).startswith('

'):\n", + " text_custom.append(f'### {div.get_text()}')\n", + " else:\n", + " text_custom.append(div.get_text())\n", + "\n", + "text_custom = '\\n'.join(text_custom)\n", + "print(text_custom[:500])" ] }, { "cell_type": "markdown", - "source": [ - "In this approach, we prioritize splitting the text at the appropriate separator, `###.` To ensure this behavior, we'll use `CharacterTextSplitter` from [LangChain](https://python.langchain.com/docs/get_started/introduction), guaranteeing such behavior. From our analysis of the text and the fact that we aim to preserve entire speaker speeches intact, we anticipate that most of them will exceed a length of 500. Hence, we'll increase the chunk size to 1000." - ], "metadata": { "id": "6CU0gC4y7Rvv" - } + }, + "source": [ + "In this approach, we prioritize splitting the text at the appropriate separator, `###.` To ensure this behavior, we'll use `CharacterTextSplitter` from [LangChain](https://python.langchain.com/docs/get_started/introduction), guaranteeing such behavior. From our analysis of the text and the fact that we aim to preserve entire speaker speeches intact, we anticipate that most of them will exceed a length of 500. Hence, we'll increase the chunk size to 1000." + ] }, { "cell_type": "code", - "source": [ - "separator = \"###\"\n", - "chunk_size = 1000\n", - "chunk_overlap = 0\n", - "\n", - "text_splitter = CharacterTextSplitter(\n", - " separator = separator,\n", - " chunk_size=chunk_size,\n", - " chunk_overlap=chunk_overlap,\n", - " length_function=len,\n", - " is_separator_regex=False,\n", - ")\n", - "\n", - "documents = text_splitter.create_documents([text_custom])\n", - "documents = [Document(text=doc.page_content) for doc in documents]\n", - "\n", - "retriever = build_retreiver(documents)\n", - "\n", - "source_nodes = retriever.retrieve(question)\n", - "print('Number of docuemnts: ',len(source_nodes))\n", - "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", - "\n", - "response = co.chat(\n", - " message=question,\n", - " documents=source_nodes,\n", - " model=co_model\n", - ")\n", - "response = response\n", - "print(response.text)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -960,14 +916,9 @@ "id": "ZFvigf6Szzev", "outputId": "99a9e061-7cad-4308-e809-1cd38ed443e1" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ "WARNING:langchain_text_splitters.base:Created a chunk of size 5946, which is longer than the specified 1000\n", "WARNING:langchain_text_splitters.base:Created a chunk of size 4092, which is longer than the specified 1000\n", @@ -997,29 +952,57 @@ ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Number of docuemnts: 5\n", "Elon Musk mentions Jonathan Nolan. Musk is friends with the creators of Westworld, Jonathan Nolan and Lisa Joy Nolan.\n" ] } + ], + "source": [ + "separator = \"###\"\n", + "chunk_size = 1000\n", + "chunk_overlap = 0\n", + "\n", + "text_splitter = CharacterTextSplitter(\n", + " separator = separator,\n", + " chunk_size=chunk_size,\n", + " chunk_overlap=chunk_overlap,\n", + " length_function=len,\n", + " is_separator_regex=False,\n", + ")\n", + "\n", + "documents = text_splitter.create_documents([text_custom])\n", + "documents = [Document(text=doc.page_content) for doc in documents]\n", + "\n", + "retriever = build_retriever(documents)\n", + "\n", + "source_nodes = retriever.retrieve(question)\n", + "print('Number of docuemnts: ',len(source_nodes))\n", + "source_nodes= [{\"text\": ni.get_content()}for ni in source_nodes]\n", + "\n", + "response = co.chat(\n", + " message=question,\n", + " documents=source_nodes,\n", + " model=co_model\n", + ")\n", + "response = response\n", + "print(response.text)" ] }, { "cell_type": "markdown", - "source": [ - "Below we validate the answer using citations." - ], "metadata": { "id": "TH62W6ek7Iom" - } + }, + "source": [ + "Below we validate the answer using citations." + ] }, { "cell_type": "code", - "source": [ - "print(insert_citations(response.text, response.citations))" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1028,14 +1011,9 @@ "id": "1wPQZRMr1aX2", "outputId": "939f6b3a-d969-487e-83d9-f64074a538e6" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Elon Musk [0] mentions Jonathan Nolan. [0] Musk is friends [0] with the creators of Westworld [0], Jonathan Nolan [0] and Lisa Joy Nolan. [0]\n" ] } + ], + "source": [ + "print(insert_citations(response.text, response.citations))" ] }, { "cell_type": "code", - "source": [ - "source_nodes[0]" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1070,14 +1053,9 @@ "id": "D9vm42za2uhE", "outputId": "eeaa7e51-19b7-4ac5-a08a-5e9f603f40fd" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "\n", " \n", " " + ], + "text/plain": [ + "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "execute_result", "data": { "text/plain": [ "{'text': \"Elon Musk -- Chief Executive Officer and Product Architect\\nYeah. The creators of Westworld, Jonathan Nolan, Lisa Joy Nolan, are friends -- are all friends of mine, actually. And I invited them to come see the lab and, like, well, come see it, hopefully soon. It's pretty well -- especially the sort of subsystem test stands where you've just got like one leg on a test stand just doing repetitive exercises and one arm on a test stand pretty well.\\nYeah.\\n### Unknown speaker\\nWe're not entering Westworld anytime soon.\\n### Elon Musk -- Chief Executive Officer and Product Architect\\nRight, right. Yeah. I take -- take safety very very seriously.\\n### Martin Viecha\\nThank you. The next question from Norman is: How many Cybertruck orders are in the queue? And when do you anticipate to be able to fulfill existing orders?\"}" ] }, + "execution_count": 18, "metadata": {}, - "execution_count": 18 + "output_type": "execute_result" } + ], + "source": [ + "source_nodes[0]" ] }, { "cell_type": "markdown", + "metadata": { + "id": "uhTrS95m9x-7" + }, "source": [ - "\n", - "# Discussion\n", + "\n", + "## Discussion\n", "\n", "This example highlights some of the concerns that arise when implementing chunking strategies. This is a field of ongoing research, and many exciting surveys have been published in domain-specific applications. For example, this [paper](https://arxiv.org/pdf/2402.05131.pdf) examines different chunking strategies in finance." - ], - "metadata": { - "id": "uhTrS95m9x-7" - } + ] } ], "metadata": { "colab": { - "provenance": [], "collapsed_sections": [ "1ivVb-oMCAaz" - ] + ], + "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/notebooks/guides/Creating_a_QA_bot_from_technical_documentation.ipynb b/notebooks/guides/Creating_a_QA_bot_from_technical_documentation.ipynb index 6b01c2d4..eab362ee 100644 --- a/notebooks/guides/Creating_a_QA_bot_from_technical_documentation.ipynb +++ b/notebooks/guides/Creating_a_QA_bot_from_technical_documentation.ipynb @@ -1,634 +1,635 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "d5-gWUEqG4-T" + }, + "source": [ + "# Creating a QA bot from technical documentation\n", + "\n", + "This notebook demonstrates how to create a chatbot (single turn) that answers user questions based on technical documentation made available to the model.\n", + "\n", + "We use the `aws-documentation` dataset ([link](https://github.com/siagholami/aws-documentation/tree/main)) for representativeness. This dataset contains 26k+ AWS documentation pages, preprocessed into 120k+ chunks, and 100 questions based on real user questions.\n", + "\n", + "We proceed as follows:\n", + "1. Embed the AWS documentation into a vector database using Cohere embeddings and `llama_index`\n", + "2. Build a retriever using Cohere's `rerank` for better accuracy, lower inference costs and lower latency\n", + "3. Create model answers for the eval set of 100 questions\n", + "4. Evaluate the model answers against the golden answers of the eval set\n" + ] }, - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# Creating a QA bot from technical documentation\n", - "\n", - "This notebook demonstrates how to create a chatbot (single turn) that answers user questions based on technical documentation made available to the model.\n", - "\n", - "We use the `aws-documentation` dataset ([link](https://github.com/siagholami/aws-documentation/tree/main)) for representativeness. This dataset contains 26k+ AWS documentation pages, preprocessed into 120k+ chunks, and 100 questions based on real user questions.\n", - "\n", - "We proceed as follows:\n", - "1. Embed the AWS documentation into a vector database using Cohere embeddings and `llama_index`\n", - "2. Build a retriever using Cohere's `rerank` for better accuracy, lower inference costs and lower latency\n", - "3. Create model answers for the eval set of 100 questions\n", - "4. Evaluate the model answers against the golden answers of the eval set\n" - ], - "metadata": { - "id": "d5-gWUEqG4-T" - } - }, - { - "cell_type": "markdown", - "source": [ - "## Setup" - ], - "metadata": { - "id": "JY2wHt3AG7X0" - } - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "wajdtJmNG0Uy" - }, - "outputs": [], - "source": [ - "%%capture\n", - "!pip install cohere datasets llama_index llama-index-llms-cohere llama-index-embeddings-cohere" - ] - }, - { - "cell_type": "code", - "source": [ - "import cohere\n", - "import datasets\n", - "from llama_index.core import StorageContext, VectorStoreIndex, load_index_from_storage\n", - "from llama_index.core.schema import TextNode\n", - "from llama_index.embeddings.cohere import CohereEmbedding\n", - "import pandas as pd\n", - "\n", - "import json\n", - "from pathlib import Path\n", - "from tqdm import tqdm\n", - "from typing import List\n" - ], - "metadata": { - "id": "kJ_9dyJxG0zA" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "# Set up Cohere client\n", - "api_key = \"\" # \n", - "co = cohere.Client(api_key=api_key)" - ], - "metadata": { - "id": "EECuI7OdIy8M" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## 1. Embed technical documentation and store as vector database\n", - "\n", - "* Load the dataset from HuggingFace\n", - "* Compute embeddings using Cohere's implementation in LlamaIndex, `CohereEmbedding`\n", - "* Store inside a vector database, `VectorStoreIndex` from LlamaIndex\n", - "\n", - "\n", - "Because this process is lengthy (~2h for all documents on a MacBookPro), we store the index to disc for future reuse. We also provide a (commented) code snippet to index only a subset of the data. If you use this snippet, bear in mind that many documents will become unavailable to the model and, as a result, performance will suffer!" - ], - "metadata": { - "id": "u_UfRVoBIHmD" - } - }, - { - "cell_type": "code", - "source": [ - "data = datasets.load_dataset(\"sauravjoshi23/aws-documentation-chunked\")\n", - "print(data)\n", - "# The data comes prechunked. We keep the data as-is in this notebook.\n", - "# For more information on optimal preprocessing strategies, please check\n", - "# our other notebooks!\n", - "\n", - "# Build a mapping from sample id to index inside data (will be useful for retrieval later)\n", - "map_id2index = {sample[\"id\"]: index for index, sample in enumerate(data[\"train\"])}\n" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "NoXezqvoG02f", - "outputId": "cabfccf3-3c15-4955-dab9-e2734fa65a7d" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", - "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", - "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", - "You will be able to reuse this secret in all of your notebooks.\n", - "Please note that authentication is recommended but still optional to access public models or datasets.\n", - " warnings.warn(\n" - ] - }, - { - "output_type": "stream", - "name": "stdout", - "text": [ - "DatasetDict({\n", - " train: Dataset({\n", - " features: ['id', 'text', 'source'],\n", - " num_rows: 187147\n", - " })\n", - "})\n" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "# Create index in vector database, and persist it for later reuse\n", - "# Note: this cell takes about ~2h on a MacBookPro\n", - "\n", - "overwrite = True # only compute index if it doesn't exist\n", - "path_index = Path(\".\") / \"aws-documentation_index_cohere\"\n", - "\n", - "# Select Cohere's new `embed-english-v3.0` as the engine to compute embeddings\n", - "embed_model = CohereEmbedding(\n", - " cohere_api_key=api_key,\n", - " model_name=\"embed-english-v3.0\",\n", - ")\n", - "\n", - "if not path_index.exists() or overwrite:\n", - " # Documents are prechunked. Keep them as-is for now\n", - " stub_len = len(\"https://github.com/siagholami/aws-documentation/tree/main/documents/\")\n", - " documents = [\n", - " # -- for indexing full dataset --\n", - " TextNode(\n", - " text=sample[\"text\"],\n", - " title=sample[\"source\"][stub_len:], # save source minus stub\n", - " id_=sample[\"id\"],\n", - " ) for sample in data[\"train\"]\n", - " # -- for testing on subset --\n", - " # TextNode(\n", - " # text=data[\"train\"][index][\"text\"],\n", - " # title=data[\"train\"][index][\"source\"][stub_len:],\n", - " # id_=data[\"train\"][index][\"id\"],\n", - " # ) for index in range(1_000)\n", - " ]\n", - " index = VectorStoreIndex(documents, embed_model=embed_model)\n", - " index.storage_context.persist(path_index)\n", - "\n", - "else:\n", - " storage_context = StorageContext.from_defaults(persist_dir=path_index)\n", - " index = load_index_from_storage(storage_context, embed_model=embed_model)\n" - ], - "metadata": { - "id": "tvgtKDBTG05h" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## 2. Build a retriever using Cohere's `rerank`\n", - "\n", - "The vector database we built using `VectorStoreIndex` comes with an in-built retriever. We can call that retriever to fetch the top $k$ documents most relevant to the user question with:\n", - "\n", - "```python\n", - "retriever = index.as_retriever(similarity_top_k=top_k)\n", - "```\n", - "\n", - "We recently released [Rerank-3](https://txt.cohere.com/rerank-3/) (April '24), which we can use to improve the quality of retrieval, as well as reduce latency and the cost of inference. To use the retriever with `rerank`, we create a thin wrapper around `index.as_retriever` as follows:" - ], - "metadata": { - "id": "sS2yzRwOKHTv" - } - }, - { - "cell_type": "code", - "source": [ - "class RetrieverWithRerank:\n", - " def __init__(self, retriever, api_key):\n", - " self.retriever = retriever\n", - " self.co = cohere.Client(api_key=api_key)\n", - "\n", - " def retrieve(self, query: str, top_n: int):\n", - " # First call to the retriever fetches the closest indices\n", - " nodes = self.retriever.retrieve(query)\n", - " nodes = [\n", - " {\n", - " \"text\": node.node.text,\n", - " \"llamaindex_id\": node.node.id_,\n", - " }\n", - " for node\n", - " in nodes\n", - " ]\n", - " # Call co.rerank to improve the relevance of retrieved documents\n", - " reranked = self.co.rerank(query=query, documents=nodes, model=\"rerank-english-v3.0\", top_n=top_n)\n", - " nodes = [nodes[node.index] for node in reranked.results]\n", - " return nodes\n", - "\n", - "\n", - "top_k = 60 # how many documents to fetch on first pass\n", - "top_n = 20 # how many documents to sub-select with rerank\n", - "\n", - "# Instantiate retriver\n", - "retriever = RetrieverWithRerank(\n", - " index.as_retriever(similarity_top_k=top_k),\n", - " api_key=api_key,\n", - ")\n" - ], - "metadata": { - "id": "Wy_BGGbGG08w" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "# Test the retriever on a single question!\n", - "query = \"What happens to my Amazon EC2 instances if I delete my Auto Scaling group?\"\n", - "\n", - "# Retrieving relevant documents with rerank now fits in one line\n", - "documents = retriever.retrieve(query, top_n=top_n)\n", - "\n", - "# Call Cohere's RAG pipeline with co.chat and the `documents` argument\n", - "resp = co.chat(message=query, model=\"command-r\", temperature=0., documents=documents)\n", - "print(resp.text)\n" - ], - "metadata": { - "id": "ODihI1YCG0_5" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "This works! With `co.chat`, you get the additional benefit that citations are returned for every span of text. Here's a simple function to display the citations inside square brackets." - ], - "metadata": { - "id": "tHTKtvMTMLhz" - } - }, - { - "cell_type": "code", - "source": [ - "def build_answer_with_citations(response):\n", - " \"\"\" \"\"\"\n", - " text = response.text\n", - " citations = response.citations\n", - "\n", - " # Construct text_with_citations adding citation spans as we iterate through citations\n", - " end = 0\n", - " text_with_citations = \"\"\n", - "\n", - " for citation in citations:\n", - " # Add snippet between last citatiton and current citation\n", - " start = citation.start\n", - " text_with_citations += text[end : start]\n", - " end = citation.end # overwrite\n", - " citation_blocks = \" [\" + \", \".join([stub[4:] for stub in citation.document_ids]) + \"] \"\n", - " text_with_citations += text[start : end] + citation_blocks\n", - " # Add any left-over\n", - " text_with_citations += text[end:]\n", - "\n", - " return text_with_citations\n", - "\n", - "grounded_answer = build_answer_with_citations(resp)\n", - "print(grounded_answer)\n" - ], - "metadata": { - "id": "7fH5mv2PG1DI" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## 3. Create model answers for 100 QA pairs\n", - "\n", - "Now that we have a running pipeline, we need to assess its performance.\n", - "\n", - "The author of the repository provides 100 QA pairs that we can test the model on. Let's download these questions, then run inference on all 100 questions. Later, we will use Command-R+ -- Cohere's largest and most powerful model -- to measure performance." - ], - "metadata": { - "id": "f1mJdBQYRI4k" - } - }, - { - "cell_type": "code", - "source": [ - "# Load data from github\n", - "url = \"https://github.com/siagholami/aws-documentation/blob/main/QA_true.csv?raw=true\"\n", - "qa_pairs = pd.read_csv(url)\n", - "qa_pairs.sample(2)\n" - ], - "metadata": { - "id": "jWkBVKSvMlip" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "We'll use the fields as follows:\n", - "* `Question`: the user question, passed to `co.chat` to generate the answer\n", - "* `Answer_True`: treat as the ground gruth; compare to the model-generated answer to determine its correctness\n", - "* `Document_True`: treat as the (single) golden document; check the rank of this document inside the model's retrieved documents" - ], - "metadata": { - "id": "eS_IDKnvcI40" - } - }, - { - "cell_type": "markdown", - "source": [ - "We'll loop over each question and generate our model answer. We'll also complete two steps that will be useful for evaluating our model next:\n", - "1. We compute the rank of the golden document amid the retrieved documents -- this will inform how well our retrieval system performs\n", - "2. We prepare the grading prompts -- these will be sent to an LLM scorer to compute the goodness of responses" - ], - "metadata": { - "id": "bi4gH235eMzA" - } - }, - { - "cell_type": "code", - "source": [ - "# Define the LLM eval prompt\n", - "# We request a score and a reason for assigning that score to 'trigger CoT' and\n", - "# improve the model response\n", - "\n", - "LLM_EVAL_TEMPLATE = \"\"\"## References\n", - "{references}\n", - "\n", - "QUESTION: based on the above reference documents, answer the following question: {question}\n", - "ANSWER: {answer}\n", - "STUDENT RESPONSE: {completion}\n", - "\n", - "Based on the question and answer above, grade the studen't reponse. A correct response will contain exactly \\\n", - "the same information as in the answer, even if it is worded differently. If the student's reponse is correct, \\\n", - "give it a score of 1. Otherwise, give it a score of 0. Let's think step by step. Return your answer as \\\n", - "as a compilable JSON with the following structure:\n", - "{{\n", - " \"reasoning\": ,\n", - " \"score: ,\n", - "}}\"\"\"\n", - "\n", - "\n", - "def get_rank_of_golden_within_retrieved(golden: str, retrieved: List[dict]) -> int:\n", - " \"\"\"\n", - " Returns the rank that the golden document (single) has within the retrieved documents\n", - " * `golden` contains the source of the document, e.g. 'amazon-ec2-user-guide/EBSEncryption.md'\n", - " * `retrieved` has a list of responses with key 'llamaindex_id', which links back to document sources\n", - " \"\"\"\n", - " # Create {document: rank} map using llamaindex_id (count first occurrence of any document; they can\n", - " # appear multiple times because they're chunked)\n", - " doc_to_rank = {}\n", - " for rank, doc in enumerate(retrieved):\n", - " # retrieve source of document\n", - " _id = doc[\"llamaindex_id\"]\n", - " source = data[\"train\"][map_id2index[_id]][\"source\"]\n", - " # format as in dataset\n", - " source = source[stub_len:] # remove stub\n", - " source = source.replace(\"/doc_source\", \"\") # remove /doc_source/\n", - " if source not in doc_to_rank:\n", - " doc_to_rank[source] = rank + 1\n", - "\n", - " # Return rank of `golden`, defaulting to len(retrieved) + 1 if it's absent\n", - " return doc_to_rank.get(golden, len(retrieved) + 1)\n" - ], - "metadata": { - "id": "rR67DcP5epAV" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "from tqdm import tqdm\n", - "\n", - "answers = []\n", - "golden_answers = []\n", - "ranks = []\n", - "grading_prompts = [] # best computed in batch\n", - "\n", - "for _, row in tqdm(qa_pairs.iterrows(), total=len(qa_pairs)):\n", - " query, golden_answer, golden_doc = row[\"Question\"], row[\"Answer_True\"], row[\"Document_True\"]\n", - " golden_answers.append(golden_answer)\n", - "\n", - " # --- Produce answer using retriever ---\n", - " documents = retriever.retrieve(query, top_n=top_n)\n", - " resp = co.chat(message=query, model=\"command-r\", temperature=0., documents=documents)\n", - " answer = resp.text\n", - " answers.append(answer)\n", - "\n", - " # --- Do some prework for evaluation later ---\n", - " # Rank\n", - " rank = get_rank_of_golden_within_retrieved(golden_doc, documents)\n", - " ranks.append(rank)\n", - " # Score: construct the grading prompts for LLM evals, then evaluate in batch\n", - " # Need to reformat documents slightly\n", - " documents = [{\"index\": str(i), \"text\": doc[\"text\"]} for i, doc in enumerate(documents)]\n", - " references_text = \"\\n\\n\".join(\"\\n\".join([f\"{k}: {v}\" for k, v in doc.items()]) for doc in documents)\n", - " # ^ snippet looks complicated, but all it does it unpack all kwargs from `documents`\n", - " # into text separated by \\n\\n\n", - " grading_prompt = LLM_EVAL_TEMPLATE.format(\n", - " references=references_text, question=query, answer=golden_answer, completion=answer,\n", - " )\n", - " grading_prompts.append(grading_prompt)\n" - ], - "metadata": { - "id": "tAg3MTOcMll4" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "## 4. Evaluate model performance\n", - "\n", - "We want to test our model performance on two dimensions:\n", - "1. How good is the final answer? We'll compare our model answer to the golden answer using Command-R+ as a judge.\n", - "2. How good is the retrieval? We'll use the rank of the golden document within the retrieved documents to this end.\n", - "\n", - "Note that this pipeline is for illustration only. To measure performance in practice, we would want to run more in-depths tests on a broader, representative dataset." - ], - "metadata": { - "id": "2BCs7ozyO1vL" - } - }, - { - "cell_type": "code", - "source": [ - "# For simplicity, prepare a DataFrame with the results\n", - "results = pd.DataFrame()\n", - "results[\"answer\"] = answers\n", - "results[\"golden_answer\"] = qa_pairs[\"Answer_True\"]\n", - "results[\"rank\"] = ranks\n" - ], - "metadata": { - "id": "1qBvMpYmQDTK" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "### 4.1 Compare answer to golden answer\n", - "\n", - "We'll use Command-R+ as a judge of whether the answers produced by our model convey the same information as the golden answers. Since we've defined the grading prompts earlier, we can simply ask our LLM judge to evaluate that grading prompt. After a little bit of postprocessing, we can then extract our model scores." - ], - "metadata": { - "id": "8Wglx0dsQtgX" - } - }, - { - "cell_type": "code", - "source": [ - "scores = []\n", - "reasonings = []\n", - "\n", - "def remove_backticks(text: str) -> str:\n", - " \"\"\"\n", - " Some models are trained to output JSON in Markdown formatting:\n", - " ```json {json object}```\n", - " Remove the backticks from those model responses so that they become\n", - " parasable by json.loads.\n", - " \"\"\"\n", - " if text.startswith(\"```json\"):\n", - " text = text[7:]\n", - " if text.endswith(\"```\"):\n", - " text = text[:-3]\n", - " return text\n", - "\n", - "\n", - "for prompt in tqdm(grading_prompts, total=len(grading_prompts)):\n", - " resp = co.chat(message=prompt, model=\"command-r-plus\", temperature=0.)\n", - " # Convert response to JSON to extract the `score` and `reasoning` fields\n", - " # We remove backticks for compatibility with different LLMs\n", - " parsed = json.loads(remove_backticks(resp.text))\n", - " scores.append(parsed[\"score\"])\n", - " reasonings.append(parsed[\"reasoning\"])\n" - ], - "metadata": { - "id": "_F3V4E56Q1CE" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "# Add scores to our DataFrame\n", - "results[\"score\"] = scores\n", - "results[\"reasoning\"] = reasonings" - ], - "metadata": { - "id": "1xksywOeQ1IJ" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "print(f\"Average score: {results['score'].mean():.3f}\")\n" - ], - "metadata": { - "id": "l8Z2w1ERSeHZ" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "### 4.2 Compute rank\n", - "\n", - "We've already computed the rank of the golden documents using `get_rank_of_golden_within_retrieved`. Here, we'll plot the histogram of ranks, using blue when the answer scored a 1, and red when the answer scored a 0." - ], - "metadata": { - "id": "ob-Km6dAPeHJ" - } - }, - { - "cell_type": "code", - "source": [ - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "\n", - "sns.set_theme(style=\"darkgrid\", rc={\"grid.color\": \".8\"})\n", - "\n", - "# create offsets for better vis\n", - "results[\"rank_shifted_left\"] = results[\"rank\"] - 0.1\n", - "results[\"rank_shifted_right\"] = results[\"rank\"] + 0.1\n", - "\n", - "f, ax = plt.subplots(figsize=(5, 3))\n", - "sns.histplot(data=results.loc[results[\"score\"] == 1], x=\"rank_shifted_left\", color=\"skyblue\", label=\"Correct answer\", binwidth=1)\n", - "sns.histplot(data=results.loc[results[\"score\"] == 0], x=\"rank_shifted_right\", color=\"red\", label=\"False answer\", binwidth=1)\n", - "\n", - "ax.set_xticks([1, 5, 0, 10, 15, 20])\n", - "ax.set_title(\"Rank of golden document (max means golden doc. wasn't retrieved)\")\n", - "ax.set_xlabel(\"Rank\")\n", - "ax.legend();\n" - ], - "metadata": { - "id": "SLn3s3n_MlpO" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "We see that retrieval works well overall: for 80% of questions, the golden document is within the top 5 documents. However, we also notice that approx. half the false answers come from instances where the golden document wasn't retrieved (`rank = top_k = 20`). This should be improved, e.g. by adding metadata to the documents such as their section headings, or altering the chunking strategy.\n", - "\n", - "There is also a non-negligible instance of false answers where the top document was retrieved. On closer inspection, many of these are due to the model phrasing its answers more verbosely than the (very laconic) golden documents. This highlights the importance of checking eval results before jumping to conclusions about model performance." - ], - "metadata": { - "id": "PZeTt7ijVKxo" - } + { + "cell_type": "markdown", + "metadata": { + "id": "JY2wHt3AG7X0" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "wajdtJmNG0Uy" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!pip install cohere datasets llama_index llama-index-llms-cohere llama-index-embeddings-cohere" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "kJ_9dyJxG0zA" + }, + "outputs": [], + "source": [ + "import cohere\n", + "import datasets\n", + "from llama_index.core import StorageContext, VectorStoreIndex, load_index_from_storage\n", + "from llama_index.core.schema import TextNode\n", + "from llama_index.embeddings.cohere import CohereEmbedding\n", + "import pandas as pd\n", + "\n", + "import json\n", + "from pathlib import Path\n", + "from tqdm import tqdm\n", + "from typing import List\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "EECuI7OdIy8M" + }, + "outputs": [], + "source": [ + "# Set up Cohere client\n", + "api_key = \"\" # \n", + "co = cohere.Client(api_key=api_key)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_UfRVoBIHmD" + }, + "source": [ + "## 1. Embed technical documentation and store as vector database\n", + "\n", + "* Load the dataset from HuggingFace\n", + "* Compute embeddings using Cohere's implementation in LlamaIndex, `CohereEmbedding`\n", + "* Store inside a vector database, `VectorStoreIndex` from LlamaIndex\n", + "\n", + "\n", + "Because this process is lengthy (~2h for all documents on a MacBookPro), we store the index to disc for future reuse. We also provide a (commented) code snippet to index only a subset of the data. If you use this snippet, bear in mind that many documents will become unavailable to the model and, as a result, performance will suffer!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "NoXezqvoG02f", + "outputId": "cabfccf3-3c15-4955-dab9-e2734fa65a7d" + }, + "outputs": [ { - "cell_type": "markdown", - "source": [ - "## Conclusions\n", - "\n", - "In this notebook, we've built a QA bot that answers user questions based on technical documentation. We've learnt:\n", - "\n", - "1. How to embed the technical documentation into a vector database using Cohere embeddings and `llama_index`\n", - "2. How to build a custom retriever that leverages Cohere's `rerank`\n", - "3. How to evaluate model performance against a predetermined set of golden QA pairs\n", - "\n" - ], - "metadata": { - "id": "4Q5i8EYDV_da" - } + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", + "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", + "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", + "You will be able to reuse this secret in all of your notebooks.\n", + "Please note that authentication is recommended but still optional to access public models or datasets.\n", + " warnings.warn(\n" + ] }, { - "cell_type": "code", - "source": [], - "metadata": { - "id": "UC2FKrkSWcPn" - }, - "execution_count": null, - "outputs": [] + "name": "stdout", + "output_type": "stream", + "text": [ + "DatasetDict({\n", + " train: Dataset({\n", + " features: ['id', 'text', 'source'],\n", + " num_rows: 187147\n", + " })\n", + "})\n" + ] } - ] -} \ No newline at end of file + ], + "source": [ + "data = datasets.load_dataset(\"sauravjoshi23/aws-documentation-chunked\")\n", + "print(data)\n", + "# The data comes prechunked. We keep the data as-is in this notebook.\n", + "# For more information on optimal preprocessing strategies, please check\n", + "# our other notebooks!\n", + "\n", + "# Build a mapping from sample id to index inside data (will be useful for retrieval later)\n", + "map_id2index = {sample[\"id\"]: index for index, sample in enumerate(data[\"train\"])}\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "tvgtKDBTG05h" + }, + "outputs": [], + "source": [ + "# Create index in vector database, and persist it for later reuse\n", + "# Note: this cell takes about ~2h on a MacBookPro\n", + "\n", + "overwrite = True # only compute index if it doesn't exist\n", + "path_index = Path(\".\") / \"aws-documentation_index_cohere\"\n", + "\n", + "# Select Cohere's new `embed-english-v3.0` as the engine to compute embeddings\n", + "embed_model = CohereEmbedding(\n", + " cohere_api_key=api_key,\n", + " model_name=\"embed-english-v3.0\",\n", + ")\n", + "\n", + "if not path_index.exists() or overwrite:\n", + " # Documents are prechunked. Keep them as-is for now\n", + " stub_len = len(\"https://github.com/siagholami/aws-documentation/tree/main/documents/\")\n", + " documents = [\n", + " # -- for indexing full dataset --\n", + " TextNode(\n", + " text=sample[\"text\"],\n", + " title=sample[\"source\"][stub_len:], # save source minus stub\n", + " id_=sample[\"id\"],\n", + " ) for sample in data[\"train\"]\n", + " # -- for testing on subset --\n", + " # TextNode(\n", + " # text=data[\"train\"][index][\"text\"],\n", + " # title=data[\"train\"][index][\"source\"][stub_len:],\n", + " # id_=data[\"train\"][index][\"id\"],\n", + " # ) for index in range(1_000)\n", + " ]\n", + " index = VectorStoreIndex(documents, embed_model=embed_model)\n", + " index.storage_context.persist(path_index)\n", + "\n", + "else:\n", + " storage_context = StorageContext.from_defaults(persist_dir=path_index)\n", + " index = load_index_from_storage(storage_context, embed_model=embed_model)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sS2yzRwOKHTv" + }, + "source": [ + "## 2. Build a retriever using Cohere's `rerank`\n", + "\n", + "The vector database we built using `VectorStoreIndex` comes with an in-built retriever. We can call that retriever to fetch the top $k$ documents most relevant to the user question with:\n", + "\n", + "```python\n", + "retriever = index.as_retriever(similarity_top_k=top_k)\n", + "```\n", + "\n", + "We recently released [Rerank-3](https://txt.cohere.com/rerank-3/) (April '24), which we can use to improve the quality of retrieval, as well as reduce latency and the cost of inference. To use the retriever with `rerank`, we create a thin wrapper around `index.as_retriever` as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Wy_BGGbGG08w" + }, + "outputs": [], + "source": [ + "class RetrieverWithRerank:\n", + " def __init__(self, retriever, api_key):\n", + " self.retriever = retriever\n", + " self.co = cohere.Client(api_key=api_key)\n", + "\n", + " def retrieve(self, query: str, top_n: int):\n", + " # First call to the retriever fetches the closest indices\n", + " nodes = self.retriever.retrieve(query)\n", + " nodes = [\n", + " {\n", + " \"text\": node.node.text,\n", + " \"llamaindex_id\": node.node.id_,\n", + " }\n", + " for node\n", + " in nodes\n", + " ]\n", + " # Call co.rerank to improve the relevance of retrieved documents\n", + " reranked = self.co.rerank(query=query, documents=nodes, model=\"rerank-english-v3.0\", top_n=top_n)\n", + " nodes = [nodes[node.index] for node in reranked.results]\n", + " return nodes\n", + "\n", + "\n", + "top_k = 60 # how many documents to fetch on first pass\n", + "top_n = 20 # how many documents to sub-select with rerank\n", + "\n", + "# Instantiate retriver\n", + "retriever = RetrieverWithRerank(\n", + " index.as_retriever(similarity_top_k=top_k),\n", + " api_key=api_key,\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ODihI1YCG0_5" + }, + "outputs": [], + "source": [ + "# Test the retriever on a single question!\n", + "query = \"What happens to my Amazon EC2 instances if I delete my Auto Scaling group?\"\n", + "\n", + "# Retrieving relevant documents with rerank now fits in one line\n", + "documents = retriever.retrieve(query, top_n=top_n)\n", + "\n", + "# Call Cohere's RAG pipeline with co.chat and the `documents` argument\n", + "resp = co.chat(message=query, model=\"command-r\", temperature=0., documents=documents)\n", + "print(resp.text)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tHTKtvMTMLhz" + }, + "source": [ + "This works! With `co.chat`, you get the additional benefit that citations are returned for every span of text. Here's a simple function to display the citations inside square brackets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "7fH5mv2PG1DI" + }, + "outputs": [], + "source": [ + "def build_answer_with_citations(response):\n", + " \"\"\" \"\"\"\n", + " text = response.text\n", + " citations = response.citations\n", + "\n", + " # Construct text_with_citations adding citation spans as we iterate through citations\n", + " end = 0\n", + " text_with_citations = \"\"\n", + "\n", + " for citation in citations:\n", + " # Add snippet between last citatiton and current citation\n", + " start = citation.start\n", + " text_with_citations += text[end : start]\n", + " end = citation.end # overwrite\n", + " citation_blocks = \" [\" + \", \".join([stub[4:] for stub in citation.document_ids]) + \"] \"\n", + " text_with_citations += text[start : end] + citation_blocks\n", + " # Add any left-over\n", + " text_with_citations += text[end:]\n", + "\n", + " return text_with_citations\n", + "\n", + "grounded_answer = build_answer_with_citations(resp)\n", + "print(grounded_answer)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f1mJdBQYRI4k" + }, + "source": [ + "## 3. Create model answers for 100 QA pairs\n", + "\n", + "Now that we have a running pipeline, we need to assess its performance.\n", + "\n", + "The author of the repository provides 100 QA pairs that we can test the model on. Let's download these questions, then run inference on all 100 questions. Later, we will use Command-R+ -- Cohere's largest and most powerful model -- to measure performance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "jWkBVKSvMlip" + }, + "outputs": [], + "source": [ + "# Load data from github\n", + "url = \"https://github.com/siagholami/aws-documentation/blob/main/QA_true.csv?raw=true\"\n", + "qa_pairs = pd.read_csv(url)\n", + "qa_pairs.sample(2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eS_IDKnvcI40" + }, + "source": [ + "We'll use the fields as follows:\n", + "* `Question`: the user question, passed to `co.chat` to generate the answer\n", + "* `Answer_True`: treat as the ground gruth; compare to the model-generated answer to determine its correctness\n", + "* `Document_True`: treat as the (single) golden document; check the rank of this document inside the model's retrieved documents" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bi4gH235eMzA" + }, + "source": [ + "We'll loop over each question and generate our model answer. We'll also complete two steps that will be useful for evaluating our model next:\n", + "1. We compute the rank of the golden document amid the retrieved documents -- this will inform how well our retrieval system performs\n", + "2. We prepare the grading prompts -- these will be sent to an LLM scorer to compute the goodness of responses" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rR67DcP5epAV" + }, + "outputs": [], + "source": [ + "# Define the LLM eval prompt\n", + "# We request a score and a reason for assigning that score to 'trigger CoT' and\n", + "# improve the model response\n", + "\n", + "LLM_EVAL_TEMPLATE = \"\"\"## References\n", + "{references}\n", + "\n", + "QUESTION: based on the above reference documents, answer the following question: {question}\n", + "ANSWER: {answer}\n", + "STUDENT RESPONSE: {completion}\n", + "\n", + "Based on the question and answer above, grade the studen't reponse. A correct response will contain exactly \\\n", + "the same information as in the answer, even if it is worded differently. If the student's reponse is correct, \\\n", + "give it a score of 1. Otherwise, give it a score of 0. Let's think step by step. Return your answer as \\\n", + "as a compilable JSON with the following structure:\n", + "{{\n", + " \"reasoning\": ,\n", + " \"score: ,\n", + "}}\"\"\"\n", + "\n", + "\n", + "def get_rank_of_golden_within_retrieved(golden: str, retrieved: List[dict]) -> int:\n", + " \"\"\"\n", + " Returns the rank that the golden document (single) has within the retrieved documents\n", + " * `golden` contains the source of the document, e.g. 'amazon-ec2-user-guide/EBSEncryption.md'\n", + " * `retrieved` has a list of responses with key 'llamaindex_id', which links back to document sources\n", + " \"\"\"\n", + " # Create {document: rank} map using llamaindex_id (count first occurrence of any document; they can\n", + " # appear multiple times because they're chunked)\n", + " doc_to_rank = {}\n", + " for rank, doc in enumerate(retrieved):\n", + " # retrieve source of document\n", + " _id = doc[\"llamaindex_id\"]\n", + " source = data[\"train\"][map_id2index[_id]][\"source\"]\n", + " # format as in dataset\n", + " source = source[stub_len:] # remove stub\n", + " source = source.replace(\"/doc_source\", \"\") # remove /doc_source/\n", + " if source not in doc_to_rank:\n", + " doc_to_rank[source] = rank + 1\n", + "\n", + " # Return rank of `golden`, defaulting to len(retrieved) + 1 if it's absent\n", + " return doc_to_rank.get(golden, len(retrieved) + 1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "tAg3MTOcMll4" + }, + "outputs": [], + "source": [ + "from tqdm import tqdm\n", + "\n", + "answers = []\n", + "golden_answers = []\n", + "ranks = []\n", + "grading_prompts = [] # best computed in batch\n", + "\n", + "for _, row in tqdm(qa_pairs.iterrows(), total=len(qa_pairs)):\n", + " query, golden_answer, golden_doc = row[\"Question\"], row[\"Answer_True\"], row[\"Document_True\"]\n", + " golden_answers.append(golden_answer)\n", + "\n", + " # --- Produce answer using retriever ---\n", + " documents = retriever.retrieve(query, top_n=top_n)\n", + " resp = co.chat(message=query, model=\"command-r\", temperature=0., documents=documents)\n", + " answer = resp.text\n", + " answers.append(answer)\n", + "\n", + " # --- Do some prework for evaluation later ---\n", + " # Rank\n", + " rank = get_rank_of_golden_within_retrieved(golden_doc, documents)\n", + " ranks.append(rank)\n", + " # Score: construct the grading prompts for LLM evals, then evaluate in batch\n", + " # Need to reformat documents slightly\n", + " documents = [{\"index\": str(i), \"text\": doc[\"text\"]} for i, doc in enumerate(documents)]\n", + " references_text = \"\\n\\n\".join(\"\\n\".join([f\"{k}: {v}\" for k, v in doc.items()]) for doc in documents)\n", + " # ^ snippet looks complicated, but all it does it unpack all kwargs from `documents`\n", + " # into text separated by \\n\\n\n", + " grading_prompt = LLM_EVAL_TEMPLATE.format(\n", + " references=references_text, question=query, answer=golden_answer, completion=answer,\n", + " )\n", + " grading_prompts.append(grading_prompt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2BCs7ozyO1vL" + }, + "source": [ + "## 4. Evaluate model performance\n", + "\n", + "We want to test our model performance on two dimensions:\n", + "1. How good is the final answer? We'll compare our model answer to the golden answer using Command-R+ as a judge.\n", + "2. How good is the retrieval? We'll use the rank of the golden document within the retrieved documents to this end.\n", + "\n", + "Note that this pipeline is for illustration only. To measure performance in practice, we would want to run more in-depths tests on a broader, representative dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1qBvMpYmQDTK" + }, + "outputs": [], + "source": [ + "# For simplicity, prepare a DataFrame with the results\n", + "results = pd.DataFrame()\n", + "results[\"answer\"] = answers\n", + "results[\"golden_answer\"] = qa_pairs[\"Answer_True\"]\n", + "results[\"rank\"] = ranks\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Wglx0dsQtgX" + }, + "source": [ + "### 4.1 Compare answer to golden answer\n", + "\n", + "We'll use Command-R+ as a judge of whether the answers produced by our model convey the same information as the golden answers. Since we've defined the grading prompts earlier, we can simply ask our LLM judge to evaluate that grading prompt. After a little bit of postprocessing, we can then extract our model scores." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_F3V4E56Q1CE" + }, + "outputs": [], + "source": [ + "scores = []\n", + "reasonings = []\n", + "\n", + "def remove_backticks(text: str) -> str:\n", + " \"\"\"\n", + " Some models are trained to output JSON in Markdown formatting:\n", + " ```json {json object}```\n", + " Remove the backticks from those model responses so that they become\n", + " parasable by json.loads.\n", + " \"\"\"\n", + " if text.startswith(\"```json\"):\n", + " text = text[7:]\n", + " if text.endswith(\"```\"):\n", + " text = text[:-3]\n", + " return text\n", + "\n", + "\n", + "for prompt in tqdm(grading_prompts, total=len(grading_prompts)):\n", + " resp = co.chat(message=prompt, model=\"command-r-plus\", temperature=0.)\n", + " # Convert response to JSON to extract the `score` and `reasoning` fields\n", + " # We remove backticks for compatibility with different LLMs\n", + " parsed = json.loads(remove_backticks(resp.text))\n", + " scores.append(parsed[\"score\"])\n", + " reasonings.append(parsed[\"reasoning\"])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1xksywOeQ1IJ" + }, + "outputs": [], + "source": [ + "# Add scores to our DataFrame\n", + "results[\"score\"] = scores\n", + "results[\"reasoning\"] = reasonings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "l8Z2w1ERSeHZ" + }, + "outputs": [], + "source": [ + "print(f\"Average score: {results['score'].mean():.3f}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ob-Km6dAPeHJ" + }, + "source": [ + "### 4.2 Compute rank\n", + "\n", + "We've already computed the rank of the golden documents using `get_rank_of_golden_within_retrieved`. Here, we'll plot the histogram of ranks, using blue when the answer scored a 1, and red when the answer scored a 0." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SLn3s3n_MlpO" + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "sns.set_theme(style=\"darkgrid\", rc={\"grid.color\": \".8\"})\n", + "\n", + "# create offsets for better vis\n", + "results[\"rank_shifted_left\"] = results[\"rank\"] - 0.1\n", + "results[\"rank_shifted_right\"] = results[\"rank\"] + 0.1\n", + "\n", + "f, ax = plt.subplots(figsize=(5, 3))\n", + "sns.histplot(data=results.loc[results[\"score\"] == 1], x=\"rank_shifted_left\", color=\"skyblue\", label=\"Correct answer\", binwidth=1)\n", + "sns.histplot(data=results.loc[results[\"score\"] == 0], x=\"rank_shifted_right\", color=\"red\", label=\"False answer\", binwidth=1)\n", + "\n", + "ax.set_xticks([1, 5, 0, 10, 15, 20])\n", + "ax.set_title(\"Rank of golden document (max means golden doc. wasn't retrieved)\")\n", + "ax.set_xlabel(\"Rank\")\n", + "ax.legend();\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PZeTt7ijVKxo" + }, + "source": [ + "We see that retrieval works well overall: for 80% of questions, the golden document is within the top 5 documents. However, we also notice that approx. half the false answers come from instances where the golden document wasn't retrieved (`rank = top_k = 20`). This should be improved, e.g. by adding metadata to the documents such as their section headings, or altering the chunking strategy.\n", + "\n", + "There is also a non-negligible instance of false answers where the top document was retrieved. On closer inspection, many of these are due to the model phrasing its answers more verbosely than the (very laconic) golden documents. This highlights the importance of checking eval results before jumping to conclusions about model performance." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Q5i8EYDV_da" + }, + "source": [ + "## Conclusions\n", + "\n", + "In this notebook, we've built a QA bot that answers user questions based on technical documentation. We've learnt:\n", + "\n", + "1. How to embed the technical documentation into a vector database using Cohere embeddings and `llama_index`\n", + "2. How to build a custom retriever that leverages Cohere's `rerank`\n", + "3. How to evaluate model performance against a predetermined set of golden QA pairs\n", + "\n" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "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.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/guides/Deep_dive_into_RAG_evaluation.ipynb b/notebooks/guides/Deep_dive_into_RAG_evaluation.ipynb index 73690b63..31eefc58 100644 --- a/notebooks/guides/Deep_dive_into_RAG_evaluation.ipynb +++ b/notebooks/guides/Deep_dive_into_RAG_evaluation.ipynb @@ -1,44 +1,34 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, "cells": [ { "cell_type": "markdown", + "metadata": { + "id": "eXdiZhdNJU6N", + "tags": [] + }, "source": [ "# Deep dive into RAG Evaluation\n", "\n", "In this notebook, we'll show you how to evaluate the output of a RAG system. The high-level RAG flow is depicted in the diagram below.\n", "![Screenshot 2024-03-11 at 10.05.47.png](data:image/png;base64,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JCABCUhAAgrQtgEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhLoCgEF6K5gNVIJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhJQgLYNSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQQFcIKEB3BauRSkACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAK0bUACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAS6QkABuitYjVQCEpCABCQggX4h8Mwzz6R58+alp556Ki266KJp6tSpaZFFFhmXxXv66afTY489ligT5Vh88cXHZTnMtAQkIAEJSEACEpCABCQwfggoQI+fujKn45wATv+tt96a5s6dmyZNmpSmTZuWVl999bTYYouN85KZfQlIQAK9TeC5554L0fWOO+5It99+e3rwwQcTf1tqqaXSKqusklZbbbW09NJLR99cL0mr1Ur33ntvOu+889KcOXPSi1/84rTpppvGffTl4yk8++yzCQYnn3xyuvPOO9Mmm2yStt566zRx4sTxVAzzKgEJSEACC0CAvp8+/4EHHgjbV70VGzd58uS07LLLhk1kYnK82bZqefxdAhKQgAR6l4ACdO/WjTnrIwIIHTfffHM69NBD05///OcY2CE+z5w5M2200UZ9VFKLIgEJSKB3COBYs9r3mmuuSaeddlq67LLL0t13350eeeSRxHes/l1++eXTy1/+8rTNNtukV73qVWnJJZdMEyZMGCgE/fcNN9yQfvzjH6cTTjghbbbZZumAAw5IG2ywQayGHrhwjH5BWHjyySdjRfOUKVNCSGgnKLPqefbs2enf//3f01VXXZXe+973ps985jNxzxhlf1Cy1AvlYbU5IgiTtIohgzD5BwlIQALzTeDhhx8OG3bxxRdH/0o/Ww280cOELPbvbW97W3rFK14RthEx2iCBQqCMN/iJXWbMoX0udPwpAQnMDwEF6Pmh5DUSGCEBnOkzzjgj/cu//EusvkPcWGGFFULE+PCHPzzC2L1dAhKQgATqBHCw77vvvnThhRemY445Jv3xj3+Mf7OFBsIz/fDjjz+ennjiiXC83/jGN6Zdd901Vjcvt9xyA6uCEaCvvfba9J3vfCcdffTRaauttkof+9jHQqwmrrEMlBFB/ZJLLkn33HNPCOkIB+221eBNnD/96U/ps5/9bPrLX/4Sk6CI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nN/rodQ348u6HeBa6vm1r31tPJf1e6vMqfd6oL7pjyh7vT+COX0hzOBer2/iog/E/lHuejulnLRz6rspbTjzfFFnTWnTf9IPYr+o+3qgnWM/m54xrsX2Mq6mj6i3NeroVa96VdivJrtPubG79IdNzGnn2C/KXy83aePD8Iw12QDSZkze5A9wL+0L+4EvVQ/cS1vj+W5iXto5zyftvB6GG6vBivqCXb2d8jyTZ9pqO1+EctM3dTJOHM73pJ3QTrFddebUL2n/5S9/CbtQr2/sFX0abb0euJZy01Yodz3AnGeTtto0VuIZI224Nflg9OHkm089wBhWZZxW/57+AOb0i02+J/0xeeY5IZ56nVFuxojYsnp/TLlpn5dffnnj2JpnstihJuakzfNB2sRTT5u80zfgO8OwHujXTj311MZnm7xS37Tzpj6RtIvf2/SMcQ/3Eke93OSD+r7ssstijMy/aU/YEGw9/SljB8Y7lLsp79yzsISFXoDmQaGRX3DBBdEp01HxwGPcaIgEOuVdd901veUtb4kGVO+gaHC///3v0zHHHNPYOeK877PPPuGE1wc/xE9aH//4xxs7KK7fa6+90rve9a4YMHJ9CeSdTunMM89MRxxxxKAHnXsxZO95z3vSa17zmkEiMJ3bTXnQw72Uvz74YdC1ww47pHe84x2Nzhyd0umnn55+97vfBbOSL36SNp0y+X79618/aOCFMcOYwI206w86BvDtb397fJrEc4z4H/7wh2BOfcGiBOqHwd4HPvCBcAbrzOnMGPT89re/TWecccagTooOhjLvvvvu0VnU65vB0gknnJB+85vfRN2VdMtPjMLnP//5GITUOxjSplP/9a9/nU488cRyy8BPOvU3vvGNad999420B7742y/U96xZs9LRRx8dzmT9ewZNe+65Z9R3fbALIwYepE2bqTs3DJa23XbbKHeTYFPaGvWNcagHOmWeEwasMKgG0maQ+4tf/CJdeumlg5hz7Xvf+9604447NjKnrZ599tnpm9/85qB2yr0YQer7da97Hf98XiBtBrqHH354OvfccweVG05ve9vboq02Ddx4LmD+3e9+d9BEC22DtPfYY4/01re+9Xnp8g/aOf0L7eWss856nvPN97TzLbfcMtobBrneXkraMCee+oCVdj5z5sz0hje8YZBjRVujvg877LB4xuoDbQYdpP3O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1lsvTZ48eaFv6AKQgAQk0KsEEBzmzJmTbrnllvS6170urbzyyh1nFaN+4403pr/+9a/pFa94RVpzzTXTpEmTOo7PGyUgAQlI4IUhwBj+jjvuSJdffnlaffXV00tf+tIRTUg+/fTTadasWenhhx9Ob33rW0PQfmFKYioSkIAEJCABCUhgMAEWSc2ePTuxaPY1r3lNLL4afFX//KXvBeinnnoqnXXWWenKK69Mm266aXr1q189osFr/1S9JZGABCTQmwQef/zxdOmll6aLL744bbXVVumVr3xlx2+uENd5550X8b3zne+MSUgF6N6sd3MlAQlIoEoAAZqJyJNOOiktv/zyaeutt05LLbVUx6ugH3zwwXTIIYfEmzDve9/70pJLLllNzt8lIAEJSEACEpDAC0aAcQ6T4uecc04smGJynMn2fg59L0DPnTs3/eY3v4nXr7fbbru0zjrruPqtn1u0ZZOABMY9AVap8dbKH//4x7T22munLbfcMk2ZMqWjcj3wwAPp9NNPT3fffXfacccd06qrrtqxmN1RBrxJAhKQgAQ6JsCWGQjQiMe77LJLvBHTyTYcOHk33HBDOvjggxP+wDbbbNOxXem4MN4oAQlIQAISkIAEKgR485c3vS666KJYdIXf28+h7wXoe+65J33/+9+PveP23HPPtMoqq3S8cqKfG4Jlk4AEJNArBNgDmlVvZ555ZvTdO+ywQ6xY6yR/d911VzrttNNi4pFZZVbRdSJedJK290hAAhKQwMgI8ErqH/7wh3iTcZ999kmrrbZaR5OI7K14xRVXpI9//OPpK1/5Stp4441dkDKyqvFuCUhAAhKQgARGSIDtItl68pRTTkkzZsxIO+200whj7O3b+16AvvPOO9PXvva1EJ733Xffvt9Tpbebm7mTgAQkMDwBhAL6blYu8zur3jh8qpNw++23h0Ffbrnl0hZbbDGi17c7Sd97JCABCUigcwJPPvlkOvXUU9MFF1yQGMevscYaHQvQbO1EHEceeWRsx+RkZOf14p0SkIAEJCABCYycAL7u9ddfn4477ri00korJbYI6+fQ9wI0h5ccdNBBMWBl0Ln00kv3c31aNglIQALjngCGmC0zWLmM+LDbbrt1vFfnrbfeGgI0b79svvnmIWQrOoz7JmIBJCCBhYQAZ7kgQLM/4gEHHDAiAZpzBfbbb7907LHHxsHk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LLoEJDD+CCBAsx3TueeeG9tncKbLSLbgYB/pI4880i04xl9TMMcSkIAEJCCBviNQBGi2B2MF9N577913ZawWqO9XQN97773piCOOSCuvvHLadttt0+KLL14tv79LQAISkECPEeA04Pvvvz+xX+eTTz6ZttlmmzgVuJNsspf0BRdckJZddtm00UYbdRxPJ2l7jwQkIAEJjIzAM888E7Zg9uzZaYcddojxfKcC9JVXXpm+/e1vpy9+8YtxLsDIcubdEpCABCQgAQlIYGQEEKBvv/32OGx5+vTpabvtthtZhD1+d98L0PPmzUs33nhjmjp1alp99dXTIoss0uNVYvYkIAEJLNwEEKARnhGPMcqrrbZax303NoDtPKZMmRKzytqAhbttWXoJSGB8EcAG3HfffemBBx6Icfy0adPShAkTFrgQ2BXiuOqqq9LGG28cfsECR+INEpCABCQgAQlIYBQJMD557LHH0p133hn+Km969XPoewGaCmXwymC1kxUT/Vz5lk0CEpBArxKg7+ZDGEnfPVrx9Con8yUBCUig3wmUsTy2oBPxufAhnmeffbbjCc0Sjz8lIAEJSEACEpDAaBFYmPzVvhegR6tRGI8EJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQksGAEF6AXj5dUSkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQwnwQUoOcTlJdJQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpDAghHoewGa/VQ4QZs94zx8asEah1dLQAISGCsCZa9O0h9J313iwQZMmjRprIpjuhKQgAQk0CEB9m3mPBf68JGcCUAcTz/9dFp00UVHtJd0h8XwNglIQAISkIAEJDCIwMKkWfa9AP3444+na665Ji2++OJpxowZafLkyYMq3D9IQAISkEDvEMAIP/HEE+muu+6KA6PouzsVobEBnCq82GKLpRVXXFEb0DvVbE4kIAEJDEsA0fiOO+5I99xzT1pvvfViPN/JQYTYlfvvvz9dfvnl6Q1veEPEM2ziXiABCUhAAhKQgAS6SIDxyaOPPppuvfXWNGXKlLT22mt3MbWxj7rvBWgGrD/72c/SKquskt71rnelJZZYYuypmwMJSEACEmhLAEN83333pfPPPz899dRTadttt03Tpk1re/1QXyBin3vuuSE+b7TRRooOQ8HyOwlIQAI9RoAV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)" - ], - "metadata": { - "id": "eXdiZhdNJU6N" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "Vi4P1tqgxJxH" + }, "source": [ - "We will focus on the evaluation of **Retrive** and **Response** (or **Generation**), and present a set of metrics for each phase. We will deep dive into each metric, to give you a full understanding of how we evaluate models and why we do it this way, and provide code so you can repdroduce on your own data.\n", + "We will focus on the evaluation of **Retrieve** and **Response** (or **Generation**), and present a set of metrics for each phase. We will deep dive into each metric, to give you a full understanding of how we evaluate models and why we do it this way, and provide code so you can repdroduce on your own data.\n", "\n", "To demonstrate the metrics, we will use data from the [Docugami's KG-RAG](https://github.com/docugami/KG-RAG-datasets/tree/main/sec-10-q/data/v1) dataset, a RAG dataset for financial 10Q filing reports. We will focus only on evaluation, without performing the actual Retrieval and response Generation steps." - ], - "metadata": { - "id": "Vi4P1tqgxJxH" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "5bnEyZUl_KmS" + }, "source": [ "# Table of content\n", "\n", @@ -46,70 +36,73 @@ "2. [Retrieval Evaluation](#retrieval-evaluation)\n", "3. [Generation Evaluation](#generation-evaluation)\n", "4. [Final Comments](#final-comments)" - ], - "metadata": { - "id": "5bnEyZUl_KmS" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "rVLK7Bhux8Bs" + }, "source": [ "\n", "## Getting Started\n", "\n", "Let's start by setting the environment and downloading the dataset." - ], - "metadata": { - "id": "rVLK7Bhux8Bs" - } + ] }, { "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "VmGk_rOco3m5" + }, + "outputs": [], "source": [ "%%capture\n", "!pip install llama-index cohere openai\n", "!pip install mistralai" - ], - "metadata": { - "id": "VmGk_rOco3m5" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "SIpPuVxfo_vz" + }, + "outputs": [], "source": [ "# required imports\n", - "import cohere\n", "from getpass import getpass\n", "import os\n", "import re\n", - "import json\n", "import numpy as np\n", - "import pandas as pd\n", "from llama_index.core import SimpleDirectoryReader\n", "from llama_index.core.llama_dataset import download_llama_dataset, LabelledRagDataset\n", "from openai import Client\n", "from mistralai.client import MistralClient" - ], - "metadata": { - "id": "SIpPuVxfo_vz" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "markdown", + "metadata": { + "id": "J0ZO3ki_yIJE" + }, "source": [ "For Response evaluation, we will use an LLM as a judge.\n", "Any LLM can be used for this goal, but because evaluation is a very challenging task, we recommend using powerful LLMs, possibly as an ensemble of models. In [previous work](https://arxiv.org/pdf/2303.16634.pdf), it has been shown that models tend to assign higher scores to their own output. Since we generated the answers in this notebook using `command-r`, we will not use it for evaluation. We will provide two alternatives, `gpt-4` and `mistral`. We set `gpt-4` as the default model because, as mentioned above, evaluation is challenging, and `gpt-4` is powerful enough to efficiently perform the task." - ], - "metadata": { - "id": "J0ZO3ki_yIJE" - } + ] }, { "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-SdZGWLTtLok", + "outputId": "46d48939-5547-4e53-de78-9ae16440107d" + }, + "outputs": [], "source": [ "# Get keys\n", "openai_api_key = getpass(\"Enter your OpenAI API Key: \")\n", @@ -120,41 +113,29 @@ "model = \"gpt-4\"\n", "# uncomment if you want to use mistral\n", "#model = \"mistral-large-latest\"\n" - ], - "metadata": { - "id": "-SdZGWLTtLok", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "46d48939-5547-4e53-de78-9ae16440107d" - }, - "execution_count": null, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter your OpenAI API Key: ··········\n" - ] - } ] }, { "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "Zk02dD_9mc7B" + }, + "outputs": [], "source": [ "if model == \"gpt-4\":\n", " client = Client(api_key=openai_api_key)\n", "else:\n", " client = MistralClient(api_key=mistral_api_key)" - ], - "metadata": { - "id": "Zk02dD_9mc7B" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "Kx4cxDGw6LI_" + }, + "outputs": [], "source": [ "# let's define a function to get the model's response for a given input\n", "def get_response(model, client, prompt):\n", @@ -163,15 +144,19 @@ " messages=[{\"role\": \"user\", \"content\": prompt}],\n", " temperature=0)\n", " return response.choices[0].message.content" - ], - "metadata": { - "id": "Kx4cxDGw6LI_" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "voJk7dPvuSdN", + "outputId": "1dd2c527-7d4a-4278-e14b-2c9479ad5caf" + }, + "outputs": [], "source": [ "# load the DocugamiKgRagSec10Q dataset\n", "if os.path.exists(\"./data/source_files\") and os.path.exists(\"./data/rag_dataset.json\"):\n", @@ -179,27 +164,13 @@ " documents = SimpleDirectoryReader(input_dir=\"./data/source_files\").load_data(show_progress=True)\n", "else:\n", " rag_dataset, documents = download_llama_dataset(\"DocugamiKgRagSec10Q\", \"./data\")" - ], - "metadata": { - "id": "voJk7dPvuSdN", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "1dd2c527-7d4a-4278-e14b-2c9479ad5caf" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "Loading files: 100%|██████████| 20/20 [01:44<00:00, 5.21s/file]\n" - ] - } ] }, { "cell_type": "markdown", + "metadata": { + "id": "lB6vO4JvMEkT" + }, "source": [ "\n", "## Retrieval Evaluation\n", @@ -213,13 +184,15 @@ "* **Mean Average Precision** (**MAP**): measures the capability of the retriever to return relevant documents at the top of the list\n", "\n", "We implement these three metrics in the class below:" - ], - "metadata": { - "id": "lB6vO4JvMEkT" - } + ] }, { "cell_type": "code", + "execution_count": 17, + "metadata": { + "id": "CooNq035eU6f" + }, + "outputs": [], "source": [ "class RetrievalEvaluator:\n", "\n", @@ -245,27 +218,40 @@ " results = {'precision': [precision],\n", " 'recall': [recall],\n", " 'map': [map]}\n", - " results = pd.DataFrame(results)\n", - " return results\n", - "\n" - ], - "metadata": { - "id": "CooNq035eU6f" - }, - "execution_count": null, - "outputs": [] + " for k,v in results.items():\n", + " print(f\"{k}: {v[0]}\")\n" + ] }, { "cell_type": "markdown", - "source": [ - "Let's now see how to use the class above to compute the results on a single datapoint." - ], "metadata": { "id": "MWW2VM-Tj8iQ" - } + }, + "source": [ + "Let's now see how to use the class above to compute the results on a single datapoint." + ] }, { "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QyMGDqaqe7fg", + "outputId": "e95242c7-dcdd-48bb-9da2-52e25a2a2d41" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Query: How has Apple's total net sales changed over time?\n", + "Golden docs: ['2022 Q3 AAPL.pdf', '2023 Q1 AAPL.pdf', '2023 Q2 AAPL.pdf', '2023 Q3 AAPL.pdf']\n", + "Retrieved docs: ['2022 Q3 AAPL.pdf', '2023 Q1 MSFT.pdf', '2023 Q1 AAPL.pdf']\n" + ] + } + ], "source": [ "# select the index of a single datapoint - the first one in the dataset\n", "idx = 0\n", @@ -282,183 +268,43 @@ "print(f'Query: {query}')\n", "print(f'Golden docs: {golden_docs}')\n", "print(f'Retrieved docs: {retrieved_docs}')" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 19, "metadata": { "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 81 }, - "id": "QyMGDqaqe7fg", - "outputId": "e95242c7-dcdd-48bb-9da2-52e25a2a2d41" + "id": "Ron8lm3Z1t1M", + "outputId": "a37eee30-c318-4a2f-8dec-bfd8f4d8c8f2" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Query: How has Apple's total net sales changed over time?\n", - "Golden docs: ['2022 Q3 AAPL.pdf', '2023 Q1 AAPL.pdf', '2023 Q2 AAPL.pdf', '2023 Q3 AAPL.pdf']\n", - "Retrieved docs: ['2022 Q3 AAPL.pdf', '2023 Q1 MSFT.pdf', '2023 Q1 AAPL.pdf']\n" + "precision: 0.67\n", + "recall: 0.5\n", + "map: 0.83\n" ] } - ] - }, - { - "cell_type": "code", + ], "source": [ "# we can now instantiate the evaluator\n", "evaluate_retrieval = RetrievalEvaluator()\n", "\n", "# and run the evaluation\n", "evaluate_retrieval.run_evals(retrieved_docs,golden_docs)\n" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 81 - }, - "id": "Ron8lm3Z1t1M", - "outputId": "a37eee30-c318-4a2f-8dec-bfd8f4d8c8f2" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " precision recall map\n", - "0 0.67 0.5 0.83" - ], - "text/html": [ - "\n", - "

\n", - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
precisionrecallmap
00.670.50.83
\n", - "
\n", - "
\n", - "\n", - "
\n", - " \n", - "\n", - " \n", - "\n", - " \n", - "
\n", - "\n", - "
\n", - "
\n" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "dataframe", - "summary": "{\n \"name\": \"evaluate_retrieval\",\n \"rows\": 1,\n \"fields\": [\n {\n \"column\": \"precision\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.67,\n \"max\": 0.67,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.67\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"recall\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.5,\n \"max\": 0.5,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.5\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"map\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 0.83,\n \"max\": 0.83,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.83\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" - } - }, - "metadata": {}, - "execution_count": 9 - } ] }, { "cell_type": "markdown", + "metadata": { + "id": "sL-sIiSl2vw9" + }, "source": [ "What are the figures above telling us?\n", "\n", @@ -467,13 +313,14 @@ "* MAP (0.83) is computed as the average of 1/1 (the highest ranked doc is correct) and 2/3 (the 2nd ranked doc is wrong, the 3rd is correct).\n", "\n", "While the example here focuses on a single datapoint, you can easily apply the same metrics to all your dataset and get the overall performance of your Retrieve phase." - ], - "metadata": { - "id": "sL-sIiSl2vw9" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "mwEyE9IaklPL", + "tags": [] + }, "source": [ "\n", "## Generation Evaluation\n", @@ -491,24 +338,28 @@ "\n", "Note that Faithfulness and Correctness share the exact same approach, the difference being that the former checks the claims against the supporting docs, while the latter against the golden answer.\n", "Also, while Correctness is measuring the precision of the claims in the response, Coverage can be seen as complementary, as it measures recall." - ], - "metadata": { - "id": "mwEyE9IaklPL" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "ySgduJrTTjvK", + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, "source": [ "### Claim Extraction\n", "\n", "Let's now see how we implement the evaluation described above using LLMs. Let's start with **claim extraction**." - ], - "metadata": { - "id": "ySgduJrTTjvK" - } + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "X2fQa0Vbuy3W" + }, + "outputs": [], "source": [ "# first, let's define a function which extracts the claims from a response\n", "def extract_claims(query, response, model, client):\n", @@ -523,25 +374,11 @@ " claims = get_response(model, client, prompt)\n", "\n", " return claims\n" - ], - "metadata": { - "id": "X2fQa0Vbuy3W" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "# now, let's consider this answer, which we previously generated with command-r\n", - "response = \"Apple's total net sales experienced a decline over the last year. The three-month period ended July 1, 2023, saw a total net sale of $81,797 million, which was a 1% decrease from the same period in 2022. The nine-month period ended July 1, 2023, fared slightly better, with a 3% decrease in net sales compared to the first nine months of 2022.\\nThis downward trend continued into the three and six-month periods ending April 1, 2023. Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022.\"\n", - "\n", - "# let's extract the claims\n", - "claims = extract_claims(query, response, model, client)\n", - "\n", - "# and see what the model returns\n", - "print(f\"List of claims extracted from the model's response:\\n\\n{claims}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -549,11 +386,10 @@ "id": "y_0NXZEfu0AJ", "outputId": "3fa32ab2-6898-449f-f062-187df7aea41e" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "List of claims extracted from the model's response:\n", "\n", @@ -565,21 +401,36 @@ "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022.\n" ] } + ], + "source": [ + "# now, let's consider this answer, which we previously generated with command-r\n", + "response = \"Apple's total net sales experienced a decline over the last year. The three-month period ended July 1, 2023, saw a total net sale of $81,797 million, which was a 1% decrease from the same period in 2022. The nine-month period ended July 1, 2023, fared slightly better, with a 3% decrease in net sales compared to the first nine months of 2022.\\nThis downward trend continued into the three and six-month periods ending April 1, 2023. Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022.\"\n", + "\n", + "# let's extract the claims\n", + "claims = extract_claims(query, response, model, client)\n", + "\n", + "# and see what the model returns\n", + "print(f\"List of claims extracted from the model's response:\\n\\n{claims}\")" ] }, { "cell_type": "markdown", + "metadata": { + "id": "50QRlCVe7dZf" + }, "source": [ "### Claim Assessment\n", "\n", "Nice! now that we have the list of claims, we can go ahead and **assess the validity** of each claim." - ], - "metadata": { - "id": "50QRlCVe7dZf" - } + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "jrg9-dlMTRpB" + }, + "outputs": [], "source": [ "# Let's create a function that checks each claim against a reference text,\n", "# which here we will call \"context\". As you will see, we will use different contexts,\n", @@ -601,40 +452,20 @@ " assessment = get_response(model, client, prompt)\n", "\n", " return assessment" - ], - "metadata": { - "id": "jrg9-dlMTRpB" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "### Faithfulness" - ], "metadata": { "id": "1OmD9pKxArk7" - } + }, + "source": [ + "### Faithfulness" + ] }, { "cell_type": "code", - "source": [ - "# Let's start with Faithfulness: in this case, we want to assess the claims\n", - "# in the response against the retrieved documents (i.e., context = retrieved documents)\n", - "\n", - "# for the sake of clarity, we report the actual text of the retrieved documents\n", - "retrieved_documents = ['Products and Services Performance\\nThe following table shows net sales by category for the three- and six-month periods ended April 1, 2023 and March 26, 2022 (dollars in millions):\\nThree Months Ended Six Months Ended\\nApril 1,\\n2023March 26,\\n2022 ChangeApril 1,\\n2023March 26,\\n2022 Change\\nNet sales by category:\\niPhone $ 51,334 $ 50,570 2 %$ 117,109 $ 122,198 (4)%\\nMac 7,168 10,435 (31)% 14,903 21,287 (30)%\\niPad 6,670 7,646 (13)% 16,066 14,894 8 %\\nWearables, Home and Accessories 8,757 8,806 (1)% 22,239 23,507 (5)%\\nServices 20,907 19,821 5 % 41,673 39,337 6 %\\nTotal net sales $ 94,836 $ 97,278 (3)%$ 211,990 $ 221,223 (4)%\\niPhone\\niPhone net sales were relatively flat during the second quarter of 2023 compared to the secon d quarter of 2022. Year-over-year iPhone net sales decreased\\nduring the first six months of 2023 due primarily to lower net sales from the Company’ s new iPhone models launched in the fourth quarter of 2022.\\nMac\\nMac net sales decreased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to lower net sales of\\nMacBook Pro.\\niPad\\niPad net sales decreased during the second quarter of 2023 compared to the second quarter of 2022 due primarily to lower net sales of iPad Pro and iPad Air.\\nYear-over-year iPad net sales increased during the first six months of 2023 due primarily to higher net sales of iPad, partially offset by lower net sales of iPad\\nmini .\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales were relatively flat during the second quarter of 2023 compared to the second quarter of 2022. Year-over-year\\nWearables, Home and Accessories net sales decreased during the first six months of 2023 due primarily to lower net sales of AirPods .\\nServices\\nServices net sales increased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to higher net sales from\\ncloud services, music and advertising.® ®\\n®\\n®\\nApple Inc. | Q2 2023 Form 10-Q | 16', 'Products and Services Performance\\nThe following table shows net sales by category for the three- and nine-month periods ended July 1, 2023 and June 25, 2022 (dollars in millions):\\nThree Months Ended Nine Months Ended\\nJuly 1,\\n2023June 25,\\n2022 ChangeJuly 1,\\n2023June 25,\\n2022 Change\\nNet sales by category:\\niPhone $ 39,669 $ 40,665 (2)%$ 156,778 $ 162,863 (4)%\\nMac 6,840 7,382 (7)% 21,743 28,669 (24)%\\niPad 5,791 7,224 (20)% 21,857 22,118 (1)%\\nWearables, Home and Accessories 8,284 8,084 2 % 30,523 31,591 (3)%\\nServices 21,213 19,604 8 % 62,886 58,941 7 %\\nTotal net sales $ 81,797 $ 82,959 (1)%$ 293,787 $ 304,182 (3)%\\niPhone\\niPhone net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales from\\ncertain iPhone models, partially of fset by higher net sales of iPhone 14 Pro models.\\nMac\\nMac net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales of laptops.\\niPad\\niPad net sales decreased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to lower net sales across most iPad models. Year-\\nover-year iPad net sales were relatively flat during the first nine months of 2023.\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales increased during the third quarter of 2023 compare d to the third quarter of 2022 due primarily to higher net sales of\\nWearables, which includes AirPods , Apple Watch and Beats products, partially offset by lower net sales of accessories. Year-over-year Wearables, Home\\nand Accessories net sales decreased during the first nine months of 2023 due primarily to lower net sales of W earables and accessories.\\nServices\\nServices net sales increased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to higher net sales from advertising, cloud\\nservices and the App Store . Year-over-year Services net sales increased during the first nine months of 2023 due primarily to higher net sales from cloud\\nservices, advertising and music.® ® ®\\n®\\nApple Inc. | Q3 2023 Form 10-Q | 16']\n", - "\n", - "# get the Faithfulness assessment for each claim\n", - "assessed_claims_faithfulness = assess_claims(query=query,\n", - " claims=claims,\n", - " context=retrieved_documents,\n", - " model=model,\n", - " client=client)\n", - "\n", - "print(f\"Assessment of the claims extracted from the model's response:\\n\\n{assessed_claims_faithfulness}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -642,11 +473,10 @@ "id": "5VmLE4yCwEMe", "outputId": "10874986-1f91-45a3-c081-dc2aae3fd618" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Assessment of the claims extracted from the model's response:\n", "\n", @@ -658,19 +488,40 @@ "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022. SUPPORTED=1\n" ] } + ], + "source": [ + "# Let's start with Faithfulness: in this case, we want to assess the claims\n", + "# in the response against the retrieved documents (i.e., context = retrieved documents)\n", + "\n", + "# for the sake of clarity, we report the actual text of the retrieved documents\n", + "retrieved_documents = ['Products and Services Performance\\nThe following table shows net sales by category for the three- and six-month periods ended April 1, 2023 and March 26, 2022 (dollars in millions):\\nThree Months Ended Six Months Ended\\nApril 1,\\n2023March 26,\\n2022 ChangeApril 1,\\n2023March 26,\\n2022 Change\\nNet sales by category:\\niPhone $ 51,334 $ 50,570 2 %$ 117,109 $ 122,198 (4)%\\nMac 7,168 10,435 (31)% 14,903 21,287 (30)%\\niPad 6,670 7,646 (13)% 16,066 14,894 8 %\\nWearables, Home and Accessories 8,757 8,806 (1)% 22,239 23,507 (5)%\\nServices 20,907 19,821 5 % 41,673 39,337 6 %\\nTotal net sales $ 94,836 $ 97,278 (3)%$ 211,990 $ 221,223 (4)%\\niPhone\\niPhone net sales were relatively flat during the second quarter of 2023 compared to the secon d quarter of 2022. Year-over-year iPhone net sales decreased\\nduring the first six months of 2023 due primarily to lower net sales from the Company’ s new iPhone models launched in the fourth quarter of 2022.\\nMac\\nMac net sales decreased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to lower net sales of\\nMacBook Pro.\\niPad\\niPad net sales decreased during the second quarter of 2023 compared to the second quarter of 2022 due primarily to lower net sales of iPad Pro and iPad Air.\\nYear-over-year iPad net sales increased during the first six months of 2023 due primarily to higher net sales of iPad, partially offset by lower net sales of iPad\\nmini .\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales were relatively flat during the second quarter of 2023 compared to the second quarter of 2022. Year-over-year\\nWearables, Home and Accessories net sales decreased during the first six months of 2023 due primarily to lower net sales of AirPods .\\nServices\\nServices net sales increased during the second quarter and first six months of 2023 compared to the same periods in 2022 due primarily to higher net sales from\\ncloud services, music and advertising.® ®\\n®\\n®\\nApple Inc. | Q2 2023 Form 10-Q | 16', 'Products and Services Performance\\nThe following table shows net sales by category for the three- and nine-month periods ended July 1, 2023 and June 25, 2022 (dollars in millions):\\nThree Months Ended Nine Months Ended\\nJuly 1,\\n2023June 25,\\n2022 ChangeJuly 1,\\n2023June 25,\\n2022 Change\\nNet sales by category:\\niPhone $ 39,669 $ 40,665 (2)%$ 156,778 $ 162,863 (4)%\\nMac 6,840 7,382 (7)% 21,743 28,669 (24)%\\niPad 5,791 7,224 (20)% 21,857 22,118 (1)%\\nWearables, Home and Accessories 8,284 8,084 2 % 30,523 31,591 (3)%\\nServices 21,213 19,604 8 % 62,886 58,941 7 %\\nTotal net sales $ 81,797 $ 82,959 (1)%$ 293,787 $ 304,182 (3)%\\niPhone\\niPhone net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales from\\ncertain iPhone models, partially of fset by higher net sales of iPhone 14 Pro models.\\nMac\\nMac net sales decreased during the third quarter and first nine months of 2023 compared to the same periods in 2022 due primarily to lower net sales of laptops.\\niPad\\niPad net sales decreased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to lower net sales across most iPad models. Year-\\nover-year iPad net sales were relatively flat during the first nine months of 2023.\\nWearables, Home and Accessories\\nWearables, Home and Accessories net sales increased during the third quarter of 2023 compare d to the third quarter of 2022 due primarily to higher net sales of\\nWearables, which includes AirPods , Apple Watch and Beats products, partially offset by lower net sales of accessories. Year-over-year Wearables, Home\\nand Accessories net sales decreased during the first nine months of 2023 due primarily to lower net sales of W earables and accessories.\\nServices\\nServices net sales increased during the third quarter of 2023 compared to the third quarter of 2022 due primarily to higher net sales from advertising, cloud\\nservices and the App Store . Year-over-year Services net sales increased during the first nine months of 2023 due primarily to higher net sales from cloud\\nservices, advertising and music.® ® ®\\n®\\nApple Inc. | Q3 2023 Form 10-Q | 16']\n", + "\n", + "# get the Faithfulness assessment for each claim\n", + "assessed_claims_faithfulness = assess_claims(query=query,\n", + " claims=claims,\n", + " context=retrieved_documents,\n", + " model=model,\n", + " client=client)\n", + "\n", + "print(f\"Assessment of the claims extracted from the model's response:\\n\\n{assessed_claims_faithfulness}\")" ] }, { "cell_type": "markdown", - "source": [ - "Great, we now have an assessment for each of the claims: in the last step, we just need to use these assessments to define the final score." - ], "metadata": { "id": "vBbLuSkO-iN7" - } + }, + "source": [ + "Great, we now have an assessment for each of the claims: in the last step, we just need to use these assessments to define the final score." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "tFk-IxK_wDVT" + }, + "outputs": [], "source": [ "# given the list of claims and their label, compute the final score\n", "# as the proportion of correct claims over the full list of claims\n", @@ -679,19 +530,11 @@ " non_supported = len(re.findall(\"SUPPORTED=0\", claims_list))\n", " score = supported / (supported+non_supported)\n", " return round(score, 2)" - ], - "metadata": { - "id": "tFk-IxK_wDVT" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "score_faithfulness = get_final_score(assessed_claims_faithfulness)\n", - "print(f'Faithfulness: {score_faithfulness}')" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -699,49 +542,34 @@ "id": "Z680DvFOW2Ea", "outputId": "1666057d-7981-43d3-f4bb-c10fdc861cae" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Faithfulness: 1.0\n" ] } + ], + "source": [ + "score_faithfulness = get_final_score(assessed_claims_faithfulness)\n", + "print(f'Faithfulness: {score_faithfulness}')" ] }, { "cell_type": "markdown", + "metadata": { + "id": "3_Ks8ELQrdQO" + }, "source": [ "The final Faithfulness score is 1, which means that the model's response is fully grounded in the retrieved documents: that's a very good news :)\n", "\n", "Before moving on, let's modify the model's response by adding a piece of information which is **not** grounded in any document, and re-compute Faithfulness." - ], - "metadata": { - "id": "3_Ks8ELQrdQO" - } + ] }, { "cell_type": "code", - "source": [ - "# let's mess up the century, changing 2022 to 1922\n", - "modified_response = response.replace('2022', '1922')\n", - "\n", - "# extract the claims from the modified response\n", - "modified_claims = extract_claims(query, modified_response, model, client)\n", - "\n", - "# and get assess the modified claims\n", - "assessed_modified_claims = assess_claims(query=query,\n", - " claims=modified_claims,\n", - " context=retrieved_documents,\n", - " model=model,\n", - " client=client)\n", - "\n", - "print(f\"Assessment of the modified claims:\\n\\n{assessed_modified_claims}\\n\")\n", - "\n", - "score_faithfulness_modified_claims = get_final_score(assessed_modified_claims)\n", - "print(f'Faithfulness: {score_faithfulness_modified_claims}')" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -749,11 +577,10 @@ "id": "YEZUA8XMAxLE", "outputId": "9b6e59b1-a4f9-46bf-cdf8-a4f520462d12" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Assessment of the modified claims:\n", "\n", @@ -767,46 +594,50 @@ "Faithfulness: 0.5\n" ] } + ], + "source": [ + "# let's mess up the century, changing 2022 to 1922\n", + "modified_response = response.replace('2022', '1922')\n", + "\n", + "# extract the claims from the modified response\n", + "modified_claims = extract_claims(query, modified_response, model, client)\n", + "\n", + "# and get assess the modified claims\n", + "assessed_modified_claims = assess_claims(query=query,\n", + " claims=modified_claims,\n", + " context=retrieved_documents,\n", + " model=model,\n", + " client=client)\n", + "\n", + "print(f\"Assessment of the modified claims:\\n\\n{assessed_modified_claims}\\n\")\n", + "\n", + "score_faithfulness_modified_claims = get_final_score(assessed_modified_claims)\n", + "print(f'Faithfulness: {score_faithfulness_modified_claims}')" ] }, { "cell_type": "markdown", - "source": [ - "As you can see, by assessing claims one by one, we are able to spot **hallucinations**, that is, the (corrupted) cases in which the information provided by the model is not grounded in any of the retrieved documents." - ], "metadata": { "id": "TccmzE9TCQsN" - } + }, + "source": [ + "As you can see, by assessing claims one by one, we are able to spot **hallucinations**, that is, the (corrupted) cases in which the information provided by the model is not grounded in any of the retrieved documents." + ] }, { "cell_type": "markdown", + "metadata": { + "id": "bPK-MND1riQD" + }, "source": [ "### Correctness\n", "\n", "As said, Faithfulness and Correctness share the same logic, the only difference being that we will check the claims against the gold answer. We can therefore repeat the process above, and just substitute the `context`." - ], - "metadata": { - "id": "bPK-MND1riQD" - } + ] }, { "cell_type": "code", - "source": [ - "# let's get the gold answer from the dataset\n", - "golden_answer = rag_dataset[idx].reference_answer\n", - "\n", - "# and check the claims in the response against the gold.\n", - "# note that assess_claims takes exactly the same args as with Faithfulness\n", - "# except for the context, that now is the golden_answer\n", - "assessed_claims_correctness = assess_claims(query=query,\n", - " claims=claims,\n", - " context=golden_answer, # note the different context\n", - " model=model,\n", - " client=client)\n", - "\n", - "\n", - "print(f\"Assess the claims extracted from the model's response against the golden answer:\\n\\n{assessed_claims_correctness}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -814,11 +645,10 @@ "id": "qVeQDVDYEr45", "outputId": "a14a5b09-b8f7-4563-ade5-fe2cd1384cfb" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Assess the claims extracted from the model's response against the golden answer:\n", "\n", @@ -830,24 +660,36 @@ "- Apple's total net sales decreased by 3% and 4% respectively, compared to the same periods in 2022. SUPPORTED=0\n" ] } + ], + "source": [ + "# let's get the gold answer from the dataset\n", + "golden_answer = rag_dataset[idx].reference_answer\n", + "\n", + "# and check the claims in the response against the gold.\n", + "# note that assess_claims takes exactly the same args as with Faithfulness\n", + "# except for the context, that now is the golden_answer\n", + "assessed_claims_correctness = assess_claims(query=query,\n", + " claims=claims,\n", + " context=golden_answer, # note the different context\n", + " model=model,\n", + " client=client)\n", + "\n", + "\n", + "print(f\"Assess the claims extracted from the model's response against the golden answer:\\n\\n{assessed_claims_correctness}\")" ] }, { "cell_type": "markdown", - "source": [ - "As mentioned above, automatic evaluation is a hard task, and even when using powerful models, claim assessment can present problems: for example, the third claim is labelled as 0, even if it might be inferred from the information in the gold answer." - ], "metadata": { "id": "V4pCRJ0qPQWT" - } + }, + "source": [ + "As mentioned above, automatic evaluation is a hard task, and even when using powerful models, claim assessment can present problems: for example, the third claim is labelled as 0, even if it might be inferred from the information in the gold answer." + ] }, { "cell_type": "code", - "source": [ - "# we can now compute the final Correctness score\n", - "score_correctness = get_final_score(assessed_claims_correctness)\n", - "print(f'Correctness: {score_correctness}')" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -855,45 +697,44 @@ "id": "nObA30PzxQha", "outputId": "2e354428-ea91-4c7e-94b6-31433018058c" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Correctness: 0.5\n" ] } + ], + "source": [ + "# we can now compute the final Correctness score\n", + "score_correctness = get_final_score(assessed_claims_correctness)\n", + "print(f'Correctness: {score_correctness}')" ] }, { "cell_type": "markdown", - "source": [ - "For Correctness, we found that only half of the claims in the generated response are found in the gold answer. Note that this is not necessarily an issue: reference answers are often non-exhaustive, especially in dataset including open-ended questions, like the one we are considering in this post, and *both* the generated and golden answer can include relevant information.\n" - ], "metadata": { "id": "4Nd0bQ3rR1c3" - } + }, + "source": [ + "For Correctness, we found that only half of the claims in the generated response are found in the gold answer. Note that this is not necessarily an issue: reference answers are often non-exhaustive, especially in dataset including open-ended questions, like the one we are considering in this post, and *both* the generated and golden answer can include relevant information.\n" + ] }, { "cell_type": "markdown", + "metadata": { + "id": "YhsEJDNXR8OY" + }, "source": [ "### Coverage\n", "\n", "We finally move to Coverage. Remember that, in this case, we want to check how many of the claims *in the gold answer* are included in the generated response. To do it, we first need to extract the claims from the gold answer." - ], - "metadata": { - "id": "YhsEJDNXR8OY" - } + ] }, { "cell_type": "code", - "source": [ - "# let's extract the golden claims\n", - "gold_claims = extract_claims(query, golden_answer, model, client)\n", - "\n", - "print(f\"List of claims extracted from the gold answer:\\n\\n{gold_claims}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -901,11 +742,10 @@ "id": "wJeHJhiAxQjy", "outputId": "8da8edf0-5605-4548-aab4-002d0202ee88" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "List of claims extracted from the gold answer:\n", "\n", @@ -917,30 +757,26 @@ "- There was a decrease in total net sales in the quarters ended April 1, 2023, and July 1, 2023.\n" ] } + ], + "source": [ + "# let's extract the golden claims\n", + "gold_claims = extract_claims(query, golden_answer, model, client)\n", + "\n", + "print(f\"List of claims extracted from the gold answer:\\n\\n{gold_claims}\")" ] }, { "cell_type": "markdown", - "source": [ - "Then, we check which of these claims is present in the response generated by the model." - ], "metadata": { "id": "6VXxxrL1SuFv" - } + }, + "source": [ + "Then, we check which of these claims is present in the response generated by the model." + ] }, { "cell_type": "code", - "source": [ - "# note that in, this case, the context is the model's response\n", - "assessed_claims_coverage = assess_claims(query=query,\n", - " claims=gold_claims,\n", - " context=response,\n", - " model=model,\n", - " client=client)\n", - "\n", - "\n", - "print(f\"Assess which of the gold claims is in the model's response:\\n\\n{assessed_claims_coverage}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -948,11 +784,10 @@ "id": "Ro-sYsp5SnOo", "outputId": "d334a72e-a87a-4900-b9e6-9a6c2140dffb" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Assess which of the gold claims is in the model's response:\n", "\n", @@ -964,15 +799,22 @@ "- There was a decrease in total net sales in the quarters ended April 1, 2023, and July 1, 2023. SUPPORTED=1\n" ] } + ], + "source": [ + "# note that in, this case, the context is the model's response\n", + "assessed_claims_coverage = assess_claims(query=query,\n", + " claims=gold_claims,\n", + " context=response,\n", + " model=model,\n", + " client=client)\n", + "\n", + "\n", + "print(f\"Assess which of the gold claims is in the model's response:\\n\\n{assessed_claims_coverage}\")" ] }, { "cell_type": "code", - "source": [ - "# we compute the final Coverage score\n", - "score_coverage = get_final_score(assessed_claims_coverage)\n", - "print(f'Coverage: {score_coverage}')" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -980,39 +822,67 @@ "id": "FUvVUN8qSnG2", "outputId": "e854432a-f13b-4596-fb7c-f9b51ee870ec" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Coverage: 0.33\n" ] } + ], + "source": [ + "# we compute the final Coverage score\n", + "score_coverage = get_final_score(assessed_claims_coverage)\n", + "print(f'Coverage: {score_coverage}')" ] }, { "cell_type": "markdown", + "metadata": { + "id": "pduSBr2-U_R7" + }, "source": [ "The Coverage score is telling us that 1/3 of the information in the gold answer is present in the generated answer. This is a useful information, that, similarly to what said above regarding Correctness, can raise further questions, such as: is it acceptable to have diverging information in the generated answer? Is any crucial piece of information missing in the generated answer?\n", "\n", "The answer to these questions is use case-specific, and has to be made by the end user: The claim-based approach implemented here supports the user by providing a clear and detailed view on what the model is assessing and how." - ], - "metadata": { - "id": "pduSBr2-U_R7" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "0-1FsN2dHzMS" + }, "source": [ "\n", "## Final Comments\n", "\n", "RAG evaluation is a hard task, especially the evaluation of the generated response. In this notebook we offer a clear, robust and replicable approach to evaluation, on which you can build on to build your evaluation pipeline." - ], - "metadata": { - "id": "0-1FsN2dHzMS" - } + ] } - ] + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "general_venv", + "language": "python", + "display_name": "general_venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/guides/Document_Parsing_For_Enterprises.ipynb b/notebooks/guides/Document_Parsing_For_Enterprises.ipynb index d5e4c51b..0076c295 100644 --- a/notebooks/guides/Document_Parsing_For_Enterprises.ipynb +++ b/notebooks/guides/Document_Parsing_For_Enterprises.ipynb @@ -18,22 +18,17 @@ "## Introduction\n", "\n", "The bread and butter of natural language processing technology is text. Once we can reduce a set of data into text, we can do all kinds of things with it: question answering, summarization, classification, sentiment analysis, searching and indexing, and more.\n", - "
\n", - "
\n", + "\n", "In the context of enterprise Retrieval Augmented Generation (RAG), the information is often locked in complex file types such as PDFs. These formats are made for sharing information between humans, but not so much with language models.\n", - "
\n", - "
\n", + "\n", "In this notebook, we will use a real-world pharmaceutical drug label to test out various performant approaches to parsing PDFs. This will allow us to use [Cohere's Command-R model](https://txt.cohere.com/command-r/) in a RAG setting to answer questions and asks about this label, such as \"I need a succinct summary of the compound name, indication, route of administration, and mechanism of action of\" a given pharmaceutical.\n", - "
\n", - "
\n", - "![image.png](data:image/png;base64,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BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABAurZBxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQTGpAAB9WNys7PSCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAkkC6i+++GK33377DdLcdttt3aGHHjqoPz0GC0yYMME98MADgwZcccUVbuWVVx7Unx4IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACzQSSBNSfe+657uCDDx60JFtssYU7+uijB/Wnx2CB9dZbzz3yyCODBlx22WVu1VVXHdSfHggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAALNBJIH1O+www5unXXWyZZq3LhxbrnllmtZwjvuuMOdfvrpWb811ljD7bzzzi3DQ8e9997rTjjhhKxz/Pjxbvfddw+D+vLz17/+tZsxY0a2bhdccIG78cYbs+8E1Pfl5malEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKAHBJIH1J900klu4sSJpav2k5/8xO25557Z8AkTJrhTTz21cNzrr7/eKThf6cMf/rA7//zzC8frx56HHXaYO+OMM7JVI6C+H7cw64QAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvSBAQH0vbIVoGQioj0DoRAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEhkCAgPohQG06SQLqmwryewQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoLMAAfWdjYZ9DALqh52cGSKAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAGBQY9QH1zz//vDv33HPdLbfc4h599FH37LPPujnnnNMtueSSbuWVV3YbbLCB+9CHPuRmn3320s07c+ZMd9FFF7n77rvP3Xvvve7xxx93K6ywQvb7SZMmufe///2lvw0DLrzwQvfAAw9knfvtt182v0suucRNnjw577/iiiu6T3ziE27rrbd2b33rW8NPB30SUD+IhB4IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBygVEdUH/PPfe4zTbbrCPKtddemwXIF404bdo0t8suu7hHHnmkaHDWb88993S77rpr26D8HXfc0V133XXZ+Aru/+Y3v+l+8YtfFE7z0EMPddtuu23hMPUkoL6UhgEIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEAygVEbUP/qq69mLcerRXqlxRZbLGv9ff7553fPPPOM+9Of/uSuv/76bNg111zj3vOe92Tf7T8F02+yySZ5L/32Yx/7mFtggQXcgw8+6H72s5/lww444AC3ww475N3xFxtQ/8lPftJdeuml2Sia5vjx491LL73k7r//fvfiiy86AupjPboRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIHhFxi1AfW33Xab22abbTKx1VZbzV1yySXujW98Y4uggu1/+MMfus0339wtvPDCLcPUsdVWW7k777wz6z9p0iT37W9/280555z5eFOmTHFbbrll3j116lS30EIL5d32iw2oV39N59RTT3XrrrtuPtrLL7/szjvvPLf44ou3BPLnI7z+hRbqYxG6EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACB9AKjNqBeAfT77rtvJrLrrru6ffbZp5LODTfc4L74xS9mv1lxxRXd5MmTBwXka+DZZ5/tDjnkkGy8Pffc0331q1/Nvsf/4oD66667zi2//PLxaF11E1DfFRMjIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACjQRGbUC9AtYVxK40btw4d+utt7o3vOENXWN885vfdOecc042/nHHHZe1Yl/043/+859u/Pjx2aANN9zQnXXWWUWjZcuiZVJSa/fHH3984Xjd9CSgvhslxkEAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBJoJjNqA+qeeesqtvfba+drPP//8bptttnGrr766W2mlldy8886bDyv6su2227qbb765aFBpP83jN7/5TeFw20L9SSed5CZOnFg4Xjc9CajvRolxEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBZgKjNqBeq/3973/fHX744YUCyyyzjNt0003dF77wBTfnnHMOGud973ufe/bZZwf179TjscceKxzFBtRfdtllbtVVVy0cr5ueBNR3o8Q4CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAM4FhD6i/8sor3Ze//OVsqSdMmOBOPfXUwjW4/vrr3Q477JANW3/99d0555xTON5tt92WDbvxxhsLhy+11FLu0ksvdWpd3qZ3v/vd7sUXX8x6HXXUUW7BBRe0gwu/zz777G6dddYpHGYD6m+99Va32GKLFY7XTU8C6rtRYhwEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKCZwLAH1F977bVup512ypb6ox/9aNbKfNEqXHfddU5B6krtAu/Db2fOnOkefPBBN2XKFHf55Ze7adOmhUFu2223dYceemjerS8TJ0509913X9ZPy7TCCiu0DK/aYQPqb7/9drfIIotUnUQ+PgH1OQVfEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBIRMY9oD6X/7yl2677bbLVqhdy/NXXXWV22233bLxPvnJT7pjjjmma4T//ve/7owzznDf+c53st+otXi1Gm/T1772tazlevU777zz3LrrrmsHV/5OQH1lMn6AAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgiMqMCwB9Q//PDD7iMf+Ui20ksttZS76aabCgFOOeUUd+SRR2bDdt99d7fHHnsUjlfWc2BgwC2xxBL54Mceeyz/ri+nnXZaHnC/8cYbu9NPP71leNUOAuqrijE+AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAwsgLDHlD/yiuvuGWWWSZf6+OPP95NmjQp79aXJ5980qlV+qeffjrrr9bmN9poo5Zxpk2blnWvsMIKLf1Dx0MPPZT/Zty4ce7OO+8Mg7LP559/3q211lruxRdfzLrPPvtst8EGG7SMEzpeeukld/XVV7u1117bLbLIIqF3yycB9S0cdCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAj0vMOwB9RI5//zz3YEHHpjj7LDDDm6NNdZwc889t/v973/v1Dr9s88+mw1fZZVV3GWXXeZmnXXWfHx9+d73vueOOOIIN378ePfpT3/aLbvssk6B80899ZS744473MUXX5wH5O+yyy7u61//esvv1fGjH/3I7b333nn/rbfe2k2YMMEtvvjiTkH006dPd1OnTnWXXHJJFnj/wx/+0K255pr5+PYLAfVWg+8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDvC4xIQP1//vMft/nmm7v77ruvo9C1117rilqhDwH1nSag1vB/8pOfuHnmmWfQqK+99po76qijsuD8QQMLehBQX4BCLwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAYJQKjEhAvaxeffVVd8EFF7ijjz46a/099tt0003dfvvtl7U6Hw9T99133+3OOOMMd8sttxT+XuPstttu7otf/KKbb7751Fma7rnnHnfAAQe4Bx54oHCc1VZbzX3iE59wkyZNKgzM14/UCv5Pf/rT7Pd33nln6XIXziDqedhhh2Xrpt5qnX/VVVeNxqATAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoKlA8oB6u0Dbbbed+9a3vmV7Dfqu1uqfeOIJ99hjj7mXXnrJLbbYYm7xxRd3c88996Bxi3ro948++qh75pln3N///nc311xzuXe84x3ZdOaYY46in5T2mzlzpps+fbp75JFH3Jvf/Ga38MILu3e+851u3nnnLf1NqgETJ04sbLGfgPpUwkwHAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBoFRjSgPotttgia4G+dZZ0FQmst956WSB/PIyA+liEbgQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAII1AkoD6p556yj300EODlmjcuHFuhRVWGNSfHoMFpk6d6mbMmDFowOqrr951a/2DfkwPBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgVKBJAH1pVNnAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACPSpAQH2PbhgWCwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQGBoBQioH1pfpo4AAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQowIE1PfohmGxEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBIZWgID6ofVl6ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAI9KkBAfY9uGBYLAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAYGgFCKgfWl+mjgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCjAgTU9+iGYbEQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEhlaAgPqh9WXqCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAj0qQEB9j24YFgsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEBgaAUIqB9a3yRTf/bZZ90pp5ySTWvllVd2EydOTDJdJjI6Ba6//no3bdq0bOE/97nPuXnmmWd0rghLjcAYEbj77ruzY/bJJ590r7zySrbWc8wxh9trr716UuDiiy92f/zjH90ss8ySLeNb3vKWnlxOFgqBMgHKTWUyY7N/L5abJk+e7O6///5sg3z1q1/tqiz3/PPPu3PPPTf7zQorrOA22mijsblBX1/rXtyuY3qDsPI9KzB9+nR31113uccff9y9+OKL+XLusssuboEFFsi7R9OXe+65x1111VXZIm+66aZu/Pjxw7L4vZIPqy5AeaCSzgU6J5BGVoBtMrL+wzX3Y4891s2YMSMrt6n8RioXuOOOO9wNN9yQjbDVVlu55ZZbrnzkUTiEYz79RvvnP//pbr31VvfYY4+55557zg0MDGQzmTBhglt11VXTz7DPp3jWWWdl+dVcc83ltt9++z5f2+FZvdFWtztUKlXLwyq3n3POOYWLs9lmm7n111+/cFg3PZte51Cn0I0y4yCAAAIIIIAAAggggAACCCAwNgUqB9Tffvvt7swzz+xa66CDDnJLLrlk1+Mz4mABBTZusMEG2YAtttjCHX300YNHos+YEdhjjz3cZZddlq3vTTfd5JZaaqkxs+6sKAKjSWDmzJlON9qvu+66QYs955xzut///veD+vdCj2233dbdfPPN2aL85je/cfPPP38vLBbLgEDXApSbuqYaEyP2YrnpK1/5irviiisyf+W3SyyxRMdt8cgjj7j11lsvG2/SpEnu+OOP7/ibfh6hF7drP3uzbqNT4MQTT3THHHNM4cKrfLr88ssXDuv1npdcconbd999s8VU3YjqSIYj9Uo+/KMf/cjtvffe2SofeeSRTsGqpJEVYJuMrP9wzf3d73539mCSro91nUwqF/j+97/vDj/88GyE008/3W288cblI4/CIRzzaTfaz3/+c/flL3+55cG/MIfDDjvMffaznw2dfHYp8L73vc+poYFernvsclVGfLSRqNvt5fuvVcvDV155ZXZ8F23I/fff3+20005Fgzr2S3GdQ51CR2ZGQAABBBBAAAEEEEAAAQQQQGDMClQOqLeVxt2oXX755W6VVVbpZlTGKREgMKwEZoz2Hu2VfSeffLI76qijsq2nlrA/8IEPjNEtyWr3u8BJJ53U8gDUuHHj8uD0+eabz1144YVDSlD3WCOgfkg3CxMfBgHKTcOAPIpm0YvlprEYUP/qq6+6pZdeOttz1lhjDffjH/+40V7Ui9u10Qrx40YCU6dOzYOqtW/svvvujabXDz+eMmWK23LLLfNVUUCVbehAwY6LLrpoPnw0fSGgfuQC6lPn5SO539W9VipaZltPykMORUL90Y+A+u63IwH13VuN9THVMv3aa6/dEkyvN6/MNttsGY0C7TfZZJO+Z0p9fiWgPt0uMxJ1u7Zc0c2aDOf916oB9Q888IDT+oSk3+ttFEp1A+pTXedQpxC2Cp8IIIAAAggggAACCCCAAAIIIBALVA6o/+lPf+oOPPDAfDovv/xyS6Vn3JLtRRddxCuoc616XwgMq+fWr7/ab7/9nALRlW655Ra3+OKLj6pVPeGEE5xela10wQUXuA996EOjavlZWAS6FQg3sDT+cN7cCMtX91gjoD4I8jlaBSg3jdYtNzTL3YvlpjoB9Y8//rj74Ac/mCFtvfXWeaufQ6OWfqqvvPKKW2aZZbIJjx8/3qmluiapF7drk/Xht80E7rjjDvepT30qm8huu+2Wt97dbKqj+9c2QERvDdx+++1H9wqZpR+pgPpeyYcnT56cPzSit5XorSXDlVLn5cO13EXzqXutVDStkdwmRctDv6ERIKC+e9d+D6jnmO9+X+g0pg0c/vjHP57VF7/pTW/q9LO+G576/KrrRpVbFltssTx4ue/QhmmFRqJut5fvvzYtD+stWTvuuGO29eoG1Ke6zqFOYZgOImaDAAIIIIAAAggggAACCCCAwCgUqBxQH6/jn//8Z7fWWmvlvR977LH8O1/SCBAYlsaRqfSGQMob172xRiwFAoMFXnrppfxhshQt8Q6eQ+c+dY81Auo72zJGbwtQburt7cPSOVcnoH60u6UOEhntHix/WgEC6gd7brbZZu6ee+7JBvzhD39wb3zjGwePNEr7jFRA/SjlSrrY/ZSX171WSgrKxEaVAAH13W+ufg+o716CMTsJHH300U4tgCv98Ic/dGuuuWann/Tl8H46v/bTBuqFul159tP91xQB9f18ndNPxw/rggACCCCAAAIIIIAAAggggMBoFiCgfhRsPQLDRsFGYhG7FuDGdddUjDiKBfRwWXj7glrZOuWUU4Z9beoeawTUD/umYoaJBSg3JQZlcskFCKhv3kJ98o3CBEe1AAH1gzdfaE1zzjnndL///e8HjzCK+xBQP3Ibr58C/upeK42cPnMeaQEC6rvfAgTUd2811sfca6+93I9//OOM4YYbbnDLLrvsmCTpp/NrP23AXqjblScB9a17VT9f57SuKV0IIIAAAggggAACCCCAAAIIIDBSAqM2oP68885z06ZNc7PMMovTK8ynT5/urr766uw1lvfdd59bZpllslZNVDE777zztvWdOXOmu+iii5x+d++992avxFxhhRXcyiuvnL0++/3vf3/b32tg02m8/PLL7uyzz3ZTpkxxd911l3vrW9/q1llnHadAzEUWWcRtsMEG2TJsscUWTq23DEWS4S233OJuvvlm98gjj2R/ms9qq63mdONIrSx/4hOfGIpZD5rm888/784999xseR599FH37LPPOgUDLLnkktl2kYeCVWefffZBvz300EPdq6++6saNG+d23nnnQcPV4/TTT3dPPvlk9vtvfOMbbrbZZiscTz1Vqf2DH/zA/fa3v832uQceeCBbFu0jWoatttrKLbzwwqW/14C///3v7uKLL3YPPvigu//++7N9TMunGwUf+9jHMletX1H6+c9/7hQkUpR23XVXN9988xUNyvppe15zzTXZ9+22284tsMAC7rLLLnO/+tWv3C9/+cvMSJWQCuxafvnlS6djB1x//fXutttuyyx+97vfuRdffNGtuOKKbpVVVnGf/vSn3Xve8x47urviiitalv/Xv/61UyuJSmuvvbZbfPHFW8bXttA2nHXWWVv6p+zQ/n3WWWdlx7v2L63D/PPPn+1fWibtXzr+4/TUU0+50047Lev9gQ98wG288cbxKO7f//63+853vuMGBgbcu971Lif3kO6+++78RtH//d//ZfuhPOWn/UiBzLqRpPxILUrq2NNrTJUXhKTXIf/mN79xc801V9ZfLTnJVK/z/dKXvpTle8oj9HpYHTfKvw477DD3zne+M0wi+/zvf/+b7YvaD+68887seNBrW+Wg5dH+vckmm2TbteWHBR3aP7WdlT71qU+58ePHZ/vdhRdemOWr8l1qqaWyZfziF7+YvXL4mWeeccccc0z2G81z7733zr6X/dPxo2NQaZtttnHvfe97y0Zt1F8e1157bWajY13HqY4R7d/almWteyo/Ofnkk/N5/+Mf/3BqdUdJ01h33XWz7+Gftt8BBxwQOpN8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BBBAAAEEEBgrAgTUj5UtzXoigAACPSwwY8YM5185nrVkrMUkCLOHNxaLNuwCBNQPOzkzrCngX4PuJk+enP1ardNPmTLFzT333DWnxs8Q6E8BBc/vs88++copiHHVVVfNu/mCAAIIIIDAcAmo5XGdg9RyttIHP/hBd+GFFw7X7JkPAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINBTAgTU99TmYGEQQACBsSOg1wgfe+yxTq9EvvLKK/MVVxDmbbfd5t72trfl/fiCwFgWIKB+LG/90bPucUDW/vvv73baaafRswIsKQLDJPCVr3zFXXHFFdnc1l13XXfeeecN05yZDQIIIIAAAq0Cf/rTn9z666+f97z88svdKqusknfzBQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAYSwIE1I+lrc26IoAAAj0k8MQTT7h11lmnZYkUTP+DH/zArbTSSi396UBgLAsQUD+Wt/7oWfdXXnkle0jqP//5j5t11lmdWqufY445Rs8KsKQIDJPA+eef7x5//PFsbltssYVbbrnlhmnOzAYBBBBAAIFWgenTp7sLLrjAzTLLLG6hhRbK3hrXOgZdCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggMDYESCgfuxsa9YUAQQQ6CmBZ555xn3uc5/Llmn++ed373//+90mm2zi3vWud/XUcrIwCIy0wF577eWmTZvmZpttNnfZZZe52WeffaQXifkjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAn0jQEB932xKVgQBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgigAB9VW0GBcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgbwQIqO+bTcmKIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCFQRIKC+ihbjIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPSNAAH1fbMpWREEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBA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AAIIIIAAAlUECKivosW4CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAn0jQEB932xKVgQBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgigAB9VW0GBcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgbwQIqO+bTcmKIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCFQRIKC+ihbjIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPSNAAH1fbMpWREEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBKgIE1FfRYlwEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBvhEgoL5vNiUrggACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBFgID6KlqMiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINA3AgTU982mZEUQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEqggQUF9Fi3ERQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEE+kaAgPq+2ZSsCAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEAVAQLqq2gxLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDfCBBQ3zebkhVBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQT+H3t3Hm/V+Pd//IN0R9xmKUKpSJLI3KyvupVCEokKDeJrljQZQskQKmlAZaiMmStEJUMKCRlTGTNkDH2p81vv63df6772PmvvM3SGOr2ux6Oz13Cttdd6rr3X7o/39VkIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURIBAfUG06IsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQZgQI1JeZS8mJIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCBREgEB9QbToiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBmBAjUl5lLyYkggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURIBAfUG06IsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQZgQI1JeZS8mJIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCBREgEB9QbToiwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFBmBAjUl5lLyYkggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIFESAQH1BtOiLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUGYECNSXmUvJiSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggURKBIAvUPPvigXXnllbne98wzz7TBgwfnWs4CBIpb4IYbbrAxY8bkeptBgwbZ2WefnWs5CxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEBg0xMokkD9hAkT7Kqrrsql16FDB7v55ptzLc+2YPXq1W51xYoVs3VjXSkIvP322/bUU0+5d27Xrp3Vq1evFI4if2+p4PzEiRNzdb7iiiusd+/euZazAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ2PYEiD9R3797dGjZs6CQrV65s++67b1bVf/75xx555BFbsGCBLVy40JYuXer6K1Bft25dO/nkk+24444zAvZZGUtk5eTJk61v377uvTRQQgMmirLNmjXL7rvvvsRd7rbbblatWjWrVauWNWrUyLbYYovEfn7hp59+al9++aWbffPNN23kyJFumkC9F+IVAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBIo8UD9ixAhr27ZtvmRXrVplF1xwgc2dOzdrf4X0BwwYkLUPK4tfoLgD9ZMmTbKBAwfmeSI1a9Y0VaBv3Lhxnn3V4YUXXrCzzz7b9SVQny8yOiGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIILBJCJRaoF6V6Dt16mTffPNNDF2vXj079NBDbe3atbZ48WJXtV4rCdTHRKU6UdKB+urVq7vz/fPPP1M+Jx5h2rRpVr9+fT+b8ZVAfUYaViCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIILBJC5RaoF4VwxV0VqtYsaJNnTrV6tatm3Ixli1bZoMHD7Zq1apRoT5FpnRmSjJQ37FjRxs2bFh8ov/5z3/s2WeftX79+tnq1avd8sqVK9ucOXOsfPnycb+kCQL1SSosQwABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFSCdS///77dtxxx8X6s2bNsn322SeeT5/4448/bOutt05fzHwJC5RmoN6f6rx589yTDfz89OnTrXbt2n428ZVAfSILCxFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEENjkBUolUN+rVy977rnnHP5JJ51kw4cPL/SF+OWXX2zChAn27rvv2ttvv21//fWXC1jXqVPH2rdvb/Xq1cu17x9//NFuuukmt1zB/hkzZrjjUaXzVq1auSroixcvtpEjR5rC/tWrV7fOnTubqur7VhT78Pv66aefbO7cufbSSy/Zxx9/bJ9//rmrwq6guM5D/zp16mQVKlTwm6S8fvnll+5YtbBRo0bWsmVLe+SRR+zVV1+NnwLQoEEDtw+dX7b29ddfO8+FCxfaggULnOXRRx9tp556qpvv27ev2/zmm2+2Dh06ZNtVgddNmjTJBg4c6LZLr1Af7uzggw82+auNGDHC2rZtG67ONU2gPhcJCxBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAgEijxQP3ff/9tNWrUiPGnTJliRx55ZDxfkAmF6Hv06GHffPNNxs0GDRpkZ511lm222WZxn6VLl1qzZs3i+fSJFi1a2GuvveZC7eG6MLxdFPvw+95rr738ZMbXAw44wEaPHm177rlnrj4aSHDCCSe45d26dbPffvvNBepzdYwWXHnllaYBDUlt0aJFpu19WD3sU7FiRTv55JNt4sSJbnFpBuoVoNexqimAf84557jpTH8I1GeSYTkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAKbtkCJB+q/+OILa9iwYayuYPoWW2wRz+d34vvvvzdVXfdtp512cpXZt9pqK1dJ3Qeutf7GG290FdZ93/QwvKrkf/vtt66iu++j1zPOOMOWLFni9qf5Y4891saNG6dJK4p9uB1Ff3ygXqH1ww8/3FXE33HHHW3lypX29NNPxwF3rVfQf7vttvObutcwUO9XyKN58+a29dZb28yZM1MGHai/9h82hehV+d23ypUru/PVQARV6V+xYoVf5V5LK1C/du1aq1u3bjzYYezYse66pxxc2gyB+jQQZhFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDACZR4oH7+/PnWoUMH9+YKfb/11luFuhRDhgyxu+66y22r6u2TJk0y7U8tJyfHFPgeOXKkm1c4fM6cOVa+fHk3H4bh69evb9OmTXPLL7roInv88cfddLt27eyOO+5w+zr11FPt9ddfd8uXL19eZPtwO4r+dO7c2VR1/fjjjzcNCAjbn3/+aT179rTZs2e7xQMGDLDu3buHXSw9UK+BBgr++9D877//bh07drT33nvPbTd48GA788wzU/Zx22232fDhw92yevXq2X333RcH97W9Ktfr2vlWWoF6VcjXUwd803XR9c3WCNRn02EdAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACm65AiQfqFVhXcF1NQfhnnnmmwPq//PKLHXjggfF2zz77rNWpUyee14RC9arQrvC8msLiqkSvFgbqFVbv16+fW65Q/sCBA930dddd5yrUa0YV7u+88063/MMPP3Sh96LYh9thPv68//77dtxxx7meTZo0cYMHws3SA/UzZsyw/fbbL+xiMjr33HPdMoXjr7766ni9QvuHHHJIXPU9yTM8X21Y3IF6XbtLL73UHePff/9tX3/9tem8nnjiifi4L7jggrhPvDBhgkB9AgqLEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMBKPFA/ZswYu+GGGxx906ZNTRXHC9oWLVrkKrpru2yh/LCauaq6q7q7WhgO79u3bxw0V1hbIW01Behbt27tpkePHm1Dhw510wsXLrSdd965SPbhdpiPP2vWrLFatWq5njVr1jQFxMMWBuozeYTn3LJlSxs7dmy8i08++cRatGiRcf++Y/v27W3BggVuNj1Qr9D/unXrfNd8v26zzTZWrVo11z8c0JBtBxUrVjQNePADJLL11ToC9XkJsR4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNU6DEA/VTpkyxK664wmk3aNDAHn300QLLT58+3VRZXq1z5852/fXXJ+7jjTfesFNOOcWtC0PkYbj82muvtS5durg+qoDeo0cPN33PPffYMccc46YnTJhgV111lZuePXu27b333imB+sLuw+3wf//88MMP9sADD9hbb71lK1ascPsP1/vpPffc0+bOnetn3WsYqG/Tpo2NGjUqZb1mfvrpJzvooIPc8qOOOsomT54c95kzZ05cjV8hdVXzT2qqan/vvfe6VWGg/p9//rF99tknaZM8l9WvX9+mTZvm+uU3UK9BGa1atcpz374DgXovwSsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIhAIlHqgPw9tJ4fDw4DJN33333aYQu9oll1xiF154YWLXzz77zJo3b+7W1a5d2xTEVwsD9UOGDLFOnTq55bNmzbJu3bq56fvuu88aN27spu+//37r37+/m37xxRetRo0aRbIPt8Poz7hx41zFdT+f7TXJLAzUn3322TZo0KBcu/j111+tbt26bvlhhx1mDz/8cNxn6tSp1qdPHzd/7rnnmqr2J7WRI0faTTfd5FYVd6Begy26du3q3kvXa+bMmfbee+/Fh6WnHJx++unxfLYJAvXZdFiHAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDApitQ4oH6Tz75xFq0aBGLL1++PJ7O70QY7Fb4WyHwpPbFF19Yw4YN3aowiL4hBerDavs60Hr16lnbtm2tcuXKtu22npcofAAAQABJREFU28andcYZZ7hpLX/99dfj5ZoIA/XnnHOODRw4MGW9ZrIF6sPK8NkC9WHwPwzU5+Tk2OOPP25r167N9b55Ldhll12sadOmrlt4HB07drRhw4albB4G/7XilVdesapVq6b0SZohUJ+kwjIEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQKPFA/e+//2516tSJ5V966SWrXr16PJ+ficcee8wuvvhi1zVTgFwr33nnHWvXrp3r16hRI1OlebUNKVDfvn17W7BggTuufv36Wc+ePd10+OfHH3+0gw8+2C0qjkD9888/b3JU69y5s11//fVuOv3P0KFDbfTo0W5xGKhP71fY+bwC9dpv79697ZlnnnFvcdJJJ9nw4cPzfDsC9XkS0QEBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNUqDEA/VSVoV6VapX+/e//22XXXaZm87vH1VoVwVztZYtW9rYsWMTN33uueesV69ebl2nTp1syJAhbnpDCdSvWbPGatWq5Y6pYsWK9sEHHySeRzgwoDgC9e+99561bt3avbeqxU+cODHxOM477zx7+umn3brSCtQvW7bMmjRpEh/fjBkzbL/99ovnkyYI1CepsAwBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEESiVQ/+STT7ogvfh32mknmzdvnm211Vb5vhorVqwwVZz3bdGiRbb99tv72fg1rGbep08fUyBcbUMJ1P/yyy924IEHumOqXbu2TZ8+3U2n/+nfv39cXb84AvWrVq2y+vXrx2+rAP8OO+wQz2ti9erVtv/++8fLSitQrwPQtZw6dao7ljZt2tioUaPi40qaIFCfpMIyBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECiVQP0///xjzZo1MwXj1Y444ggbP368bbvttilXRP0efvhhUyX3rl27pqxThXpVqldTcP6KK65IWR9WXdeKV155xapWrer6bCiBeh2MQuoKq6uFx+gWRH8WLlxoJ510kp+14gjUa+fh4IMLL7zQLrnkkvg9NaHQ+rBhw+JlpRmo/+yzz6x58+bxscycOdP23XffeD59gkB9ugjzCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIICCBUgnU642fe+4569WrlyZdq1mzprVr187q1atn69ats48++shUyV7B+O7du9uAAQN8V/eqML1C9b6deeaZLniuUL5C6Kpi7lunTp1syJAhfnaDqVCvAwqD7Hvuuad17tzZmjZtahpMMHv2bLvxxhvj49ZEcQXqVZVe/r7p2hx//PG22Wab2TPPPJOrCnxpBup1jKFb27ZtbcSIEf7Qc70SqM9FwgIEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQiARKLVAv/Tlz5rhQva/QnumK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56LPfoUKFeL12tZXuE8P1KuTguAHHnhg3N9PlEag/r333jNdJzUF2v119MdUUq/hIJBBgwaZrntBmyr633333W4zAvVmK1asMIW31Tp16mRDhgxx0/n5o6eZaECH2gcffGD6jOenFVeg/sorr7QHH3zQHcKcOXPMv09+jmlD6aP/g+lJC2obY5X9DcWR40AAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEJFCoQP348eNNIVvfFJoMqwFr+a+//moKxs6bN8+eeeYZ35XXjVigJAP1YtJn7Mwzz8wlRqA+F0mJLnjiiSfsggsucO957LHH2rhx4xLff926dSlVwVWZffPNN0/sGy7s379/XHFZgeYWLVqEq+PpMBR7zTXXWNeuXeN1mSaKOlCve1x6OD7Te2dbroEHGoCg9uyzz1qdOnUSuycF6v/nf/7HVHE9vZVGoD68drpfHHXUUemHVSLzJ5xwgr399tvuvT755BM30KOgb0ygvqBimftvaIH6zEe68axRmF6herVevXqZ7oc0BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBwgkUOFD/559/2tFHHx1Xh7711lutffv2Gd9d1ey33nrrjOtZsfEIlHSgXpW/33jjDdtyyy1TkAjUp3CU+Ex+A/U6MFUrV9VytQULFtguu+ziprP90SCK2bNnuy4vvPCC1axZM7E7gfr/Y0lyKulA/V9//WX77ruvOyh9d998803bYost/u8gS3DKDzxQJXRVRC9MI1BfGLXkbQjUJ7usz9I1a9ZYrVq13C70OV+8eHGpfd/W5zzYFgEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDYEAQKHKifNGmSDRw40B37+oYmf/nlF5swYYK9++67rpqwApm1a9d21ZkV0q9Xr16i0ZAhQ0zb1q9f33777Td74IEHbOXKldasWTPr27ev/dd//Zepjyq4VqhQwVTBedCgQW653+F//vMfU1XrtWvXWvXq1V1163vvvddV1FeYd88997TDDz/c2rRpY02bNvWbZXxVFeQpU6a48LCCbWoNGjSwAw44wO171113Tdz2q6++sjFjxrh1GqjQsmXLXP0UnLvhhhssJyfH9tlnH+vSpUtK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6Dy892QbFNG0adN4v1999VXiKZflQL0Gs+W3+fvBxhyoj55WEF9vDSApyqZBft4oHOhVlO/BvhBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBTUFgM51kQcrkf/nll3b00UfHm0TBd6tTp048n9fEihUrrFGjRnG3RYsW2fbbbx/P+4kovG1RBWY326dPHzvvvPP8Ktt///1t9erV1rZtWxsxYoRb/uuvv1rdunXddBQys6h6vJv+6KOP7Nhjj3XTQ4cOtdNOO81NRyHnlOPWfrS/9BaF/i2q4J5rey2IwvZ28cUXu3X16tWzqFq1mw7/ROFt0zodr1pUudkaNGgQd4mqStuhhx7q5g877DB7+OGH43V+Iqpwb1G4M2OfqJq/nXDCCW59VDHcokrfftP4NfRJf59Vq1ZZFECN+77zzju2ww47xPOa0PHL3beoGq516NDBz67XaxQMt8aNG8f7ePPNN23XXXeN5zXx1FNPWTSAImWZZqIwoUVB83h569atLQqjuvmk89AKXSd9RnybN2+e7bHHHm526dKl1qxZMzcdBZKtU6dObnrWrFnWrVs3Nx1VpY+P9/7777f+/fu75VEVe6tRo4ab7tKli7388stuevDgwRYNVHDThf3z559/2n777ZeyeVQl2qJAcsqykpiJKrvbBRdc4N5K361x48ZlfdukYz/77LMtGmjitgs/v35H0WAVO/HEE/1s4uuVV15p0VMn3LooSG5R5e/EfuFCve8LL7zgFmX6zof9k6bDfYwcOdKikGxStwItO+KII+ybb75x22S7px588MEWVT93/UaPHm3RwISU94kC2nbUUUelLPMz8+fPt0qVKvnZIn/9/vvv43tbFGS36dOn5/keY8aMsWiAjOvXsmVL072uKJp3qlixokWDlgq1y6j6d/wZzc/9Lqokb9FAI/de+r3S71Z6W7JkibVq1SpeHFVHt3LlysXzfuL999+Pr23Hjh1t2LBhflWer7rXROFq1y8abGU77bRTrm30W6jPj1r0pBk78sgjc/VJXxDeG/Xd1Hc0vy38HZ0zZ47ttdde+drU96tZs2b8vU3fMLznR09lsPLly6d3yTWv3239fqtFAzmsevXqufr4BeH9qTC/r//884/ts88+fneW7fsdd8rnRHjf0O/etttum88t6YYAAggg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dZ8PPclk1113dZ/zPfbYI8/fKA1M0FNU9H8NDSjTYLzS/F0ry9eJc0MAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFNR6DIAvUbG1mmQP3Gdh4cLwIIILChCTz11FN2/vnnu8PKVkl/QztujgeBDV1Ag//0dBI1PYVDT+OgIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIrJ8AgfrIL6xQv36cbI0AAgggsG7dOpszZ47pde+993aVtFFBAIH1F9BTbL744gtXlb5x48brv0P2gAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggYATqow8BgXq+CQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAwKYnQKA+uuYE6je9Dz5njAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIbLKB+j///NNOPvlk9wmoW7euDR06lE8DAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAwCYksMkG6jeha8ypIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCQIEKhPQGERAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQNkXIFBf9q8xZ4gAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQIECgPgGFRQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJlX4BAfdm/xpwhAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQIIAgfoEFBYhgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIlH0BAvVl/xpzhggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIJAgTqE1BYhAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFD2BQjUl/1rzBkigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIJAgQqE9AYRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBA2RcgUF/2rzFniAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJAgQKA+AYVFCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAmVfgEB92b/GnCECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAggCB+gQUFiGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgiUfQEC9WX/GnOGCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgkCBOoTUFiEAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUPYFCNSX/WvMGSKAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggkCBCoT0BhEQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEDZFyBQX/avMWeIAAIIIIAAAggggAACCCCAAAIIIIAAArYcRs4AAAGnSURBVAgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggkCBAoD4BhUUIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACZV+AQH3Zv8acIQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECCAIH6BBQWIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCJR9AQL1Zf8ac4YIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCQIE6hNQWIQAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQ9gUI1Jf9a8wZIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCQI/D8AAAD//6zs0/QAAEAASURBVOx9Cdy2Q/X/vLy2JGu2bNn3nSxZ/4jImryWQkQiWxKVqGxZXllSilK0iLIrlD1lVxJF2uQNlcjW5vnPd36dq3PPM9c2M/d9X8/zfM/n8zzXdc8163dmzpw5c2Zm0oglQyICRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwwRCYRIP6CVbjLC4RIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACDgEaFDPhkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAG9WwDRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwIRGgQf2ErHYWmggQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEaFDPNkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAhMSARrUT8hqZ6GJABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIHD00UebK6+80rzhDW8wd9xxh5k8eTKBaYHAfvvt53BbeumlzWWXXUb8WmBHr0SACBABIkAEiAARIAJEgAh0A4FxbVB/+eWXm4ceesghfcghh5jZZ5+9FvVHHnnE3HDDDc7fFltsYZZbbrnaMOPZwwUXXGBefPFF8/rXv97ss88+47moLBsRGCoC4Dvg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xLvjjju6Awimn376Hnf+qEeAfa0eo0H6oEH9INFmWkSACBABIkAEiAARIAJEgAgQASJABFoi8Morr5h3vvOdLtRKK61kTj755JYx0DsRIAJEoD0CDzzwgPn4xz/uAuKE3V133bV9JAxBBDqMAMfXDlcOs0YEOozAE088Ya699lpz1113mccff9xMmzbN5XaVVVYxSy+9tJkyZYpZc801O1wCZo0IEAEiQASIABEgAkRgIiLAOfBErHWWmQikIUD9cBp+4zk0Dhv4/ve/b2A8j3XLtdde22y99dY8WCCy0tnXIoHrUzAa1PcJWEZLBIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIwvhEYGRkxkyZNGt+FZOmIABEgAkSACBABIkAEiAARIAJEgAgQASJABIjAOEeABvXjvIJZPCJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARCCNAg/owLnQlAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEIFxjgAN6sd5BbN4RIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASIQRoAG9WFc6EoEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAuMcARrUj/MKZvGIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRCCMAA3qw7jQlQgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAExjkCNKj3KviRRx4xN9xwg3PdYostzHLLLef5GNzPl19+2UyaNMnMMsssg0v0vymNjIyYv/3tb2a22WYzkydPHnj6OsHnn3/eXHjhhc4J9YF6IY0tBL7xjW+Yxx9/3LXnI444YihtemwhxtzmRmDq1KnmxRdfNLPPPrs55JBDckffmfjAL4855phgflZccUWz3377Bb8NwrFL4+sgyss0uo3At7/9bXPHHXcEM4lxapFFFgl+67fjeJZ5BsGH+1WvF1xwgRtDXv/615t99tmn381g3MT/1FNPmfPPP9+VZ5111qEMP25qlgUhAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIjD+EKBBvVenMMT58Ic/7FxPOeUUs8suu3g++vfz3//+t7nsssvMfffdZ+69917zxBNPuMQWWGABs/LKK5v3vve9BsYomhBm//33N6+99lrhPMMMM5jFF1/c/S222GJm6aWXNnPMMUfxPfSC8Pfcc4+54oor3POxxx4rvCGulVZayRx00EEuruLDgF6AwyabbOJS22GHHcxnP/vZAaXMZHIh8J73vMfceuutLrr777/fzD333LmiZjxEoBECyy+/vHnppZdc20MbHK8E48V11103WLyNN97YfPWrXw1+G4TjMMfXQZSPaYwtBD72sY+Ziy++OJhpyEKrrbZa8Fu/HcezzDMIPtyvel199dXNX/7yFzPrrLOaX/ziF/1uBuMm/gceeMBsv/32rjz77rtv6YavcVNgFoQIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEYswiMC4P6c845x5x66qmuEnAS9vrrrx9dIcMy+HvuuefMBz/4QXP77bdX5n277bYzZ511VuHn1VdfNcsss0zxu+zl+OOPN7vvvruZbrrpgl623HJLg9OD6+iAAw4wRx11VJ23rN/Hs3FZVqAGEFlsX6NB/QAqh0lUIjAIQ87KDAzo49///vdiPESS2ESAjVqgGIP62D7vEvT+DWt89bIx5n/mrJMxD0ZCAa6++mq3gVCigPwlGxnbGtTffffdZuedd3ZRHXbYYebQQw+VaFs/x7PMMwg+nLNedeXFGtSPp/66xx57FPOURx99tNFtQzSo162I70SACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiECXERgXBvVnnnmmmTp1qsP5oosuMhtuuGE05pdffnlhCIWT0HEier8JxlO77babmTZtWpHUKqusYtZaay3zr3/9yzz4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2HoH6utxTFpzoL4ez9esY2gbjSpQmtfAMWve9957L54nuseosWO1xf6WaY5Affr5mnWPsL9B1Wg2bVOP+3A9nq9Z5rUcV7u88BzRdlZS6nG92mWEe5o+9XxrzqJe0MP69TulnFKPQH097sNhW6sN1NfrN48N1Msy/VzS9Wifbfr3WbFy2mmnxWMSjo3+rVduyTq3CNSXq0c9BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIG2JrCIdsiVWZKQmNtkk01cElj1c2y11VYuCem6Lbfc0r377rsuCae5G264oWBpe+21l/vTn/5UMC7padAlAQE/LglauBVWWKFgur6ceeaZLgmh+fFJWNF17969UZ0wIunh2W2zzTbhq+vTp49LAj+uU6dObpFFFnGLLrqo69Wrlx+OlZKB999/3yU9P9tR7p577nGXXXaZH5f0xOh+/OMfF0zv0qWLW3HFFQvG1frljjvucIcddlhczMYbb+ySwIW31rY/+eSTLgnRR/fjjz/eJQ0HfP0kIO3WX3/9OO/AgQNdEmR1c+bMcUkDiDiPKiy99NIu6anT6bjZouO54YYb2lH+uBaMSH3Zeuut3R577JEaW/vXpJGG0zlhSxJcdknDDD9K256EHu1kt9JKK7nOnTu7F1980R9nTUx6qnZ77723r/f3v//d7bfffn44CQC5Hj16+OGkx2KXBIH9cBK4cjq29ViGX2Dy59BDD3VJgwb/NQm5uFNOOcV973vfc9qfpDdX9+abb4aq/pikr53p06e73Xff3dfRuXjSSSfF+mHg448/dl27dvVfZZNexty5c/21E65ZHbfDDz/caXt07ic9bvp91gJkqPO/Xbt2YfGNPqu91upxzSc9BsfzQBum46trfc0113RJIxSXhJJcErpySejJn/e6H2l/s8rBBx/s7r77bj/p4YcfdquttlpWtUbjdN0lvYj78TLU9aZ7je6NuqedddZZBfOsssoq7tFHHy0Y98ADD7h99923YFzS4MBfTx06dHA6X+09U/ej9H2oYObki90fTdO1nvRO6hZffPF01bp9nzlzpttll13i8pIAluvbt6+/jl566SU3cuRIvw2xQjKQBMBdv3797Ch//DRi3XXXdUkAumBa+KLjnITg/Fedt+3btw+T/Keub7mp6LgkjRT88nQPHDFiRDzHNV3Pm/Q9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LL300u6xxx5zyy67bIvtHytGYEES0NsbFEb90Y9+1OjNIOodeOedd/abuzBdOwrPH3fccfEwTZw40W2++ebxOwMIILDgCHz99ddu1KhR7oILLvAbRQOYBefYVLMl9QzU640rBx10kPvHP/7hN2Xw4MHuiCOOqGazmAcBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEgEC9ZwGCCCAQDMK1CNQf+utt7onnnjCh6jUO2koxxxzjDv66KPDVz4RWOgFxowZ48455xy3yiqruL59+7rOnTu7hoYGp17aQ8/0QhoxYoQbOHDgQuFl32ixww47uCuuuGKh2G92EoHWJDB69Gj35ptvusmTJ8ee6bX9V199tdt2221b066wrUag1kD93Llz3ciRI90HH3zg9FswFDUKmzp1qlt++eXDKD4RQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoEIBAvUVglEdAQQQqEWgHoF69S6tXqZt+cUvfuGDw4sttpgdzTACC7VACNQXQzjwwAPdCSec4Nq1a1esWpuZNn78ePfqq6/6/dlzzz3d+uuv32b2jR1BoK0IqCd6BeptOfPMM13//v3tKIZbmUCtgfrXXnvNbbfddgV7rTD9tdde6zbZZJOC8XxBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgcoECNRX5kVtBBBAoCaB6dOnu2HDhvllqEfsasJxCgnfddddTuH5rl27uq222sr16dNnoQkE13QAmHmhElBP9Lfffrt77LHH3AsvvBADqt26dXPrrbee+/Wvf+222GKLhcqEnUUAgQVf4IADDnBvvfWW69Chg9tyyy1dz549Xffu3Rf8DWcLiwoMHjzYzZw50/9+mzhxYsW/29599103aNAgv44VVljB/ehHP3K77LKLW2eddYqul4kIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUFqAQH1pI2oggAACCCCAQBsRaGhocIssskgb2Rt2AwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoFYBAvW1CjI/AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCA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NAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECtAgTqaxVkfgQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFWKUCgvlUeNjYaAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoFYBAvW1CjI/AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQKsUIFDfKg8bG40AAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQqwCB+loFmR8BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEECgVQoQqG+Vh42NRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEKhVgEB9rYLMjwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINAqBQjUt8rDxkYjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII1CpAoL5WQeZHAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQaJUCBOpb5WFjoxFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQRqFSBQX6sg8yOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0SgEC9a3ysDXfRn/99dfuoYceci+++KJ766233LfffutXvtFGG7k99tij+TakzmsaOXKk+/TTT91yyy3njjrqqDovPX9xkydPdjNnzvQVBg0a5NefX7vppowdO9bv/zLLLOMOOOCAplsRSy5bYEE5N8re4AW84rx581y7du1c+/btF/AtLdy84cOHu3feeadwZPJt8cUXd+eee26j8YxAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIHaBCoK1L/++utu2LBhmWvs2LGjW3vttd1aa63ldtxxR6egLqV1CyhEf/DBB7vnn3++0Y706dPHXXTRRY3G13vEmWee6WbPnh0Xe84557gVVlghfq92YMMNN3SfffaZX9Y///nPahdT8XzHHHOMmzhxop/v/vvvd507d654GfWYYbPNNnPvv/++W3rppd1zzz1Xj0WyjBoFFpRzo8bdaNHZn3nmGXfjjTe6xx9/PDZc2XTTTd1WW23lBgwY4NZcc80W3b5yVr799tu7V199NbPqK6+8kjmekQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUL1ARYF69ay9yy67lFybQrrHH3+822effdyiiy5asv6CUGHgwIFuypQpflNmzZrlllxyyQVhs1p0G/r37+/+8Y9/xG1Q+HuppZby33fYYQf3+9//Pk5rigEF3hV8t+W8885z/fr1s6OqGiZQ33KB+gsuuMCdffbZ/rhdffXVbtttt63qGLb0TF999ZXr0qWL3wwFtm+44YaaNolAfU18/k0aeubkFTXEueqqq9wPfvCDvCoLxPjzzz/fvffee3FbrrjiijhMoD5SMIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBA3QRqCtSH3rW//vrrzB51TzrpJHfggQfWbWObckF77rmn79VY61CP3WoUsDAX9U7fq1cvT7DGGmv4XtW/+93vNivJ3Xff7XvItyutV8/4LRWoP+GEE5xC5CoPPfRQi/WYHXrB1rENDUmsc1MOjx492o0cOdKv4sorr3Q9evRoytU12bK//PJLt+666/rld+vWzd166601rWtBOTdq2okWmvnhhx92e++9d1z7Kqus4nr37u3mz5/v7rjjDv82Ck3UfV3HKTSEiDMswAM77bRTfEsIgfoF+ECxaQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAq1WoOpAvQKLjz76aNzxb775xk2fPt2dcsop7l//+lccf++998bQaRy5AA4QqC88KAp7h96ejz32WHfUUUcVVmiGb+oB//rrr2+0ptmzZ7sOHTo0Gl/JiJYK1FeyjW21LoH6tnpkW26//u///s89+OCDfgP0tgD1RN++fXv//cMPP3S77bZbbPQ1aNAgd9ppp7Xcxla4ZgL1FYJRHQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIEKBeoWqA/rfffdd13Pnj1jj8Cnn366U9hxQS8E6guP0E033eQUpFc544wz3IABAworNPE3vfVgk0028efRCius4H7xi1+4Sy+91K/1iiuucDvssENNW0Cgvia+mmYmUF8THzOnBF5//XW3zTbbxLH//Oc/ne4ZtsyYMcP17dvXj1Iv9U8++aRbcsklbZUFdphA/QJ7aNgwBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBNiJQ90C9XGzP4gMHDnQjRozI5Jo7d64bN26ce+aZZ3zv9l988YX7wQ9+4DbaaCO3xx57uG7dumXOp5ETJkxwc+bMcYsssogbMmRIZjjynnvucVOmTPHL2H///d1aa63lh/Vn1KhR7u23347fb7311tgIQOHtJZZYIk7TQJcuXdyBBx5YMM5++fzzz32vyE8//bR76qmnfG/I2pcf/vCHrl+/fu5HP/qRrd5kww888IC76667nAKkelOA3iSw2WabuU033dTtu+++sdfm9AaoR/o77rgjjp41a5Y/Jhqh46AAui0a179/fzuqrsPTpk1zv/zlL/0y99prL9/DdAj1q4GGGmqUKpMmTXJ6Q8IjjzzidG5tt912rkePHm7vvfd2G2+8cQzrK4Abyvvvv+/OPvts//VnP/uZu/vuu92dd97p3XbZZRc3dOhQb3vBBRe4v//9765z585O5/gBBxwQFlHwed999/n1F4z835fDDz/cderUKWuSH/ef//zHaT0q22+/vfvJT37ibrzxRvePf/zD75fGb7HFFn5/tG3FymWXXebeeuutRlW+853vuCOPPLLR+KwR4XrVufLSSy85WSmcvPbaa/vzvHfv3t63Xbt2BbPfcsstBQZPPPGEe/75530dBaHXXHPNgvqLLbaYP76LLrpowfjwRdd+eAvGCSec4LS+a665xul4h/E6vrvuuqu30T6GovPg8ccf98cuXKfajzXWWMPfd3TNqnHNqquuGmaJ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0+Wicsghh/jrwX8xfz799FO30UYb+THaJm1buqgxSF7jgnRdfU8H6vXWCIWAZZAXHFewW72zq7f3couuGTWY0XLTPcMXC9TbnsAVfNcxLLdoPWrco/tBuuic0LmnN06EhjjlLP+TTz5xul7UU716h7dF54B6jk+XWs+NsDw1pNF1qjd2pIvOBzVUyfOxb3LQudaxY8f0IgqC3KXuobrnan22zJkzJ/bWb8c31fAll1zi9F/6fNI1JXPdg0sVvdlD53k5z7j0snQc9Bx44oknCiapYYMaguhYVbv8O+64wzcM07LtdThmzJh4nyhYKV8QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQKAsgYoC9WUtsYpK6uVZYX2FBLt06eKD0e3atStrSQ0NDT4srOCmeinefPPNy+ohu6yFV1FJPfMrlK1e0tUYYOWVV3bf//73M8OqVSy+rFm++OILp0CytkPh6PXWW88tv/zyZc3b1irNnTvXN3KYN2+e23TTTd2KK67Y1nax2fZHDU5eeuklp8YK7733nltmmWXcqquu6oPHSy21VLNtRz1W9M477/h90afuOepdv9x7Tj3WX+9l6Dx/4YUXnHpJVw/r2qfWdkzqafLWW2/56759+/aua9euFTX0qHU79Bx67bXX/Pk1f/58H6BfffXVa10s8yOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQBMJLBCB+ibaNxaLAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECuAIH6XBomIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCLRlAQL1bfnosm8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuQIE6nNpmIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQlgUI1Lflo8u+IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOQKEKjPpWECAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQFsWIFDflo8u+4YAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQK0CgPpeGCQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJtWYBAfVs+uuwbAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQK4AgfpcGiYggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIItGUBAvVt+eiybwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK5AgTqc2mYgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCWBQjUt+Wjy74hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII5AoQqM+lYQICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAWxYgUN+Wjy77hgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJArQKA+l4YJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAm1ZgEB9Wz667BsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBArgCB+lwaJiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0ZQEC9W356LJvCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAArkCBOpzaZiAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg0JYFCNS35aPLviGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkChCoz6VhAgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBbFiBQ35aPLvuGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggkCtAoD6XhgkIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACbVmAQH1bPrrsGwIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECuAIH6XBomIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCLRlAQL1bfnosm8IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuQIE6nNpmIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDQlgUI1Lflo8u+IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOQKEKjPpWECAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQFsWIFDflo8u+4YAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQK0CgPpeGCQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJtWYBAfVs+uuwbAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQK4AgfpcGiYggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIItGUBAvVt+eiybwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK5AgTqc2mYgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIINCWBQjUt+Wjy74hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII5AoQqM+lYQICCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAWxYgUN+Wjy77hgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJArQKA+l4YJCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAm1ZgEB9Wz667BsCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBArgCB+lwaJiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0ZQEC9W356LJvCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAArkCBOpzaZiAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg0JYFCNS35aPLviGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkChCoz6VhAgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEBbFlioA/XDhw933377rVt55ZXdwQcf3OaO8+TJk93MmTP9fg0aNMgtt9xybW4fm3uHXn75ZTdt2jT36quvus8++yyu/je/+Y1bccUV43cGSgvMnTvXjRs3zlf8wQ9+4HbeeefSM1EDAQQQQACBNizQEs/Gpvo9rN+g+i2qome8nvWU/wpMmjTJzZgxw3856qij+I1e5MTQb+7we3G77bZzO+64Y5HabX/S9OnT3eWXX565o7vvvvtC75MJU8XIsWPHuk8//dQts8wy7oADDqhiCZXNsiDch5vyWuN/l6jsfKA2AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgi0jEDZgfqrr77aB4nDZvbr18/16NEjfI2fX3/9tRsyZIj7//bOA16PqszDJ5RIERWJAiEsRVEEWRAIC1ICiIjSRTpSliaKrMCClAQEQZEWCJHFDS4aCEgXWBBEQJpLU9oidUEBDVUpAiEY7p7/Wd7Z95s785X55t773eR5f79kyjlz5sxz6tzvf96ZNWtWdu473/lOTwpFllpqqZTH5ZZbLvzqV7/K8ju77Bx44IHhsssuS49z0003hWWXXXZ2ebQheY5JkyaFU045pfDe1113XVh++eULw+o6KWHaiSeemCW3/vrrh9122y07Hm47Tz75ZNhggw1SttWfnHbaacPtEYYsv7fffns4++yz277/UUcdFZZZZpnUh5955pnpurXXXjvstddebaXx0EMPhZNPPjnFXWWVVYLEfzLlQXlpx+aZZ54wZcqUflHPOOOM8Lvf/S6d18KUsWPH9ovT6sT1118fNEa1a0sssUSQcMnsxRdfDIceeqgdttzusMMO4Qtf+EKKd+GFF4Y77rgju0Ziv2222SY7zu/ovi+//HI6rYVOK6+8cj4KxxCAwBxMYCjGxoGaD1900UXhkEMOSaWp+cv2228/B5ds46MfcMAB4Yorrkgnb7755rD00ks3RuAoI6Ax1urOfvvtl94zs8A5cOfKK68M3/zmNwuf/Igjjgj77rtvYRgnOyOw6qqrpvnaggsuGH7/+993dnGF2L3QDw9kW+PvEhUqBZdAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAKDTqBtQb3/EVS5lJj3pz/9ab8M33bbbWHnnXduOP9f//VfYfTo0Q3neuFgoH647oVnUx58mSGo765U7rzzzrDddttliUhcIYGy2VlnnRWWXHJJOxyQrQTnEydOzNJefPHFg9rWiBEjsnMDvTN58uRw0kknpdtIwCxRdlUbCtFg1bz22nVepNhO3n7+85+Hz3zmM0n4baK0cePGhalTp7ZzeZAn3W9961sp7i677BKOP/74tO/7mHYS+uMf/9gvmrx+2oImieu32GKLfnFanZCw/7vf/W6raFm4FhepTzR76qmn0phmx622XrD2r//6r+Hiiy/OLlHfoK9YaFtka665Zpg+fXoK0uKGTTfdtCjabHVOdebWW29Nz/TII4+E+eeff7Z6Ph4GAnUS6GZsrDpGD9R82I9VCOobawmC+kYezY4GUuTb7L69Gvbf//3fQW3LTH2GjbF+fmLhbKsRQFBf7+IV/87Qyd8l7rrrrrDtttumQlQa9j5SrVS5CgIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEBzApUF9UpWXoUXWWSRhjvIy6889npDUO9pDN7+4YcfnnltvuWWW4IJpgYvB7PPnbwIQN6+JQIebNtoo43C448/3nDba6+9NnzqU59qODeQB6effno49dRT0y3OPffcwq9UtHv/p59+Oqy77rop+k477RS+//3vt3vpHB/v6quvDhMmTMg4zJgxI7zxxhvZcb5fnjZtWqonEnJL0C37h3/4h0yAlV1YsuNFmuPHjw977713iikRu8T2ZuZ53Y59PkaOHNngyd3iDISg3t/X7uO3+iqJH6f+9Kc/hc0339xHybzI66TE8fPNN18WfvDBB2cLx/KCekVS2ZR5/58TBfUSQkkQJZOX17LFBikC/0FgDifQzdhYdYy2+WHdX2zyi7G0KFBfo8H+jwCC+vZrAoL65qz0lax99tknRUJQ35xVJ6F6R1F/3Ml8uZP083F7oR8eyLZW9e8S+juSvgwl23///bOvnuT5cQwBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgDgJdCerz3ibffvvt5AXZCzuVSQT1dRQVaQwlga222irce++9KQsStUscPJgmz97rrbdev1tqAcs3vvGNfucH6kRVsd5A5Yd0/4/An//857DWWmtlOIo8wSvw3XffbfiygjyzzzXXXNl1ZTtHHnlkOO+881Lwj3/846DFHUV2xRVXBIkEZRtvvHGYMmVKUbSGc3UL6r/61a+G4447ruEeVQ688P2aa64JK664YmEyRYJ6Cfp/85vfNIjw7WKf7pzioR5BvZU+WwgMLIGqY/RACTkH9mmHd+oI6tsvv4EU+bafi96NiaC+d8umk5z1Qj/ci20NQX0ntYi4EIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAtwQqCeo//elPB31u/rOf/Wy44IILsjzceOONYY899kjH8pr98MMPp30E9RkidoYpgVVXXTV5rJZnZXlYHmybOnVq5pH829/+dvjBD36QsrDyyiuHK6+8ctCyU1WsN2gZnENv1K6gXng23XTT1H9r/5577gkf+chHtNvUdt1113DzzTenOL/61a+CvBgXGYL6/6dywgknhB133PH/T7y3h6AeD/X9KgUnIFATgapjdC8IOWtCMGySQVDfflH1osi3/dwPfEwE9QPPeDDu0Av9cC+2NQT1g1H7uAcEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIGAEKgnqJ0yYEL773e+mNO6+++7w0Y9+NO0feOCB4bLLLgsbbrhhmDVrVibALBPU9/X1hauuuip58n3wwQeTyFOfVV9llVWSN+6vfOUrYcSIEZbXpttf/vKX4bbbbksi/oceeijIS76E/5/5zGeSqLHIu3D+h2stCLjpppvCr3/96/SJ99VXXz09y7777hvmmWeewvvPmDEj3HXXXUHX3nfffem6l19+OX0eXvfUwgJ55x09enTh9c8++2yYPHlyCtOn5b/whS+ESy65JDGRcFWmfOy0005hk002Scdl/91www3pawBF4fJivvDCCxcFNZz7+9//Hi6//PJULvJerU/dS0Su/H/iE58In//85xOTD37wgw3Xff/73w+vvvpq4v3666+HadOmheeffz5ssMEG4bDDDgvve9/7guJI9DHffPOFL37xi+Goo45K5xsSqvFAnuR/9rOfpXql+iUTS9WL3XffPau3RbccP358EAszv3CkSCR70EEHNU3P0qm61T3l8Vp2++23p0/em8f8O++8Myy22GJtJa22IQH+I488EsREdXXZZZdN9VTtbdy4cWHuuefO0pJAWu3XTAJscZVpQY21IQvXteobiryev/XWW2HixInJS7rFt+0//uM/hi222MIOm27rKFfVZ4nZqrR5y5zqx7HHHtvwPOr79G+wrRNBvRfx/ed//mdYaaWVUnbVZ6oNy/QFhlGjRqV9/ad2/OSTT6bjRx99tNDzugLndEH9+uuvn8YPsVh88cXTmJQfOwZaUK+vEKhtaxyTMEpj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)" + "\n", + "![Document Parsing Result](https://github.com/cohere-ai/notebooks/raw/main/notebooks/images/document-parsing-2.png)" ] }, { "cell_type": "markdown", - "metadata": { - "id": "f-mq1FCojI2p" - }, + "metadata": {}, "source": [ "\n", "## PDF Parsing\n", @@ -47,7 +42,7 @@ "\n", "By way of example, we will be parsing a [21-page PDF](https://www.accessdata.fda.gov/drugsatfda_docs/label/2023/215500s000lbl.pdf) containing the label for a recent FDA drug approval, the beginning of which is shown below. Then, we will perform a series of basic RAG tasks with our different parsings and evaluate their performance.\n", "\n", - "![image.png](data:image/png;base64,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)" + "![Drug Label Snippet](https://github.com/cohere-ai/notebooks/raw/main/notebooks/images/document-parsing-1.png)" ] }, { @@ -212,7 +207,7 @@ "### Solution 1: Google Cloud Document AI [[Back to Solutions]](#top)\n", "\n", "Document AI helps developers create high-accuracy processors to extract, classify, and split documents.\n", - "
\n", + "\n", "External documentation: https://cloud.google.com/document-ai" ] }, @@ -224,13 +219,13 @@ "source": [ "#### Parsing the document\n", "\n", - "The following block can be executed in one of two ways\n", - "1. Inside a Google Vertex AI environment\n", - " - No authentication is needed\n", - "2. Inside the notebook\n", - " - Authentication needed\n", - " - There are pointers inside the code on which lines to uncomment in order to achieve that\n", - "
\n", + "The following block can be executed in one of two ways:\n", + "- Inside a Google Vertex AI environment\n", + " - No authentication needed\n", + "- From this notebook\n", + " - Authentication is needed\n", + " - There are pointers inside the code on which lines to uncomment in order to make this work\n", + "\n", "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" ] }, @@ -364,47 +359,35 @@ "id": "CT4QwMTwLPad", "outputId": "1c85c3aa-a3b5-48c4-bb6e-5033c2c604a0" }, - "outputs": [ - { - "data": { - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - }, - "text/plain": [ - "'\\nPost process parsed document and store it locally.\\nMake sure to run in Google Vertex AI environment or include a credentials file.\\n'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "\"\"\"\n", "Post process parsed document and store it locally.\n", - "Make sure to run in Google Vertex AI environment or include a credentials file.\n", + "Make sure to run this in a Google Vertex AI environment or include a credentials file.\n", "\"\"\"\n", "\n", - "# from pathlib import Path\n", - "# from collections import defaultdict\n", + "\"\"\"\n", + "from pathlib import Path\n", + "from collections import defaultdict\n", "\n", - "# parsed_documents = []\n", - "# combined_versioned_parsed_documents = defaultdict(list)\n", + "parsed_documents = []\n", + "combined_versioned_parsed_documents = defaultdict(list)\n", "\n", - "# # Assemble versioned documents together ({\"doc_name\": [(0, doc_content_0), (1, doc_content_1), ...]}).\n", - "# for filename, doc_content in versioned_parsed_documents:\n", - "# filename, version = \"-\".join(filename.split(\"-\")[:-1]), filename.split(\"-\")[-1]\n", - "# combined_versioned_parsed_documents[filename].append((version, doc_content))\n", + "# Assemble versioned documents together ({\"doc_name\": [(0, doc_content_0), (1, doc_content_1), ...]}).\n", + "for filename, doc_content in versioned_parsed_documents:\n", + " filename, version = \"-\".join(filename.split(\"-\")[:-1]), filename.split(\"-\")[-1]\n", + " combined_versioned_parsed_documents[filename].append((version, doc_content))\n", "\n", - "# # Sort documents by version and join the content together.\n", - "# for filename, docs in combined_versioned_parsed_documents.items():\n", - "# doc_content = \" \".join([x[1] for x in sorted(docs, key=lambda x: x[0])])\n", - "# parsed_documents.append((filename, doc_content))\n", + "# Sort documents by version and join the content together.\n", + "for filename, docs in combined_versioned_parsed_documents.items():\n", + " doc_content = \" \".join([x[1] for x in sorted(docs, key=lambda x: x[0])])\n", + " parsed_documents.append((filename, doc_content))\n", "\n", - "# # Store parsed documents in local storage.\n", - "# for filename, doc_content in parsed_documents:\n", - "# file_path = \"{}/{}-parsed-{}.txt\".format(data_dir, \"gcp\", source_filename)\n", - "# store_document(file_path, doc_content)" + "# Store parsed documents in local storage.\n", + "for filename, doc_content in parsed_documents:\n", + " file_path = \"{}/{}-parsed-{}.txt\".format(data_dir, \"gcp\", source_filename)\n", + " store_document(file_path, doc_content)\n", + "\"\"\"" ] }, { @@ -440,9 +423,7 @@ "\n", "### Solution 2: AWS Textract [[Back to Solutions]](#top)\n", "\n", - "[Amazon Textract](https://aws.amazon.com/textract/) is an OCR service offered by AWS. It can detect text, forms, tables, and more in PDFs and images. In this section, we go over how to use Textract's asynchronous API.\n", - "
\n", - "
" + "[Amazon Textract](https://aws.amazon.com/textract/) is an OCR service offered by AWS. It can detect text, forms, tables, and more in PDFs and images. In this section, we go over how to use Textract's asynchronous API." ] }, { @@ -460,7 +441,7 @@ "id": "vFBasw782Gho" }, "source": [ - "We assume you are working within the AWS ecosystem (from a SageMaker notebook, EC2 instance, a Lambda function, ...) with valid credentials. Much of the code here is from supplemental materials created by AWS and offered here:\n", + "We assume that you are working within the AWS ecosystem (from a SageMaker notebook, EC2 instance, a Lambda function, etc.) with valid credentials. Much of the code here is from supplemental materials created by AWS and offered here:\n", "\n", "- https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/textract\n", "- https://github.com/aws-samples/textract-paragraph-identification/tree/main\n", @@ -769,8 +750,7 @@ "id": "kpF9UagY01-l" }, "source": [ - "Next, we set up Textract and S3, and provide this to an instance of `TextractWrapper`.\n", - "\n" + "Next, we set up Textract and S3, and provide this to an instance of `TextractWrapper`." ] }, { @@ -987,7 +967,7 @@ "### Solution 3: Unstructured.io [[Back to Solutions]](#top)\n", "\n", "Unstructured.io provides libraries with open-source components for pre-processing text documents such as PDFs, HTML and Word Documents.\n", - "
\n", + "\n", "External documentation: https://github.com/Unstructured-IO/unstructured-api" ] }, @@ -1002,7 +982,7 @@ "The guide assumes an endpoint exists that hosts this service. The API is offered in two forms\n", "1. [a hosted version](https://unstructured.io/)\n", "2. [an OSS docker image](https://github.com/Unstructured-IO/unstructured-api?tab=readme-ov-file#dizzy-instructions-for-using-the-docker-image)\n", - "
\n", + "\n", "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" ] }, @@ -1092,7 +1072,7 @@ "### Solution 4: LlamaParse [[Back to Solutions]](#top)\n", "\n", "LlamaParse is an API created by LlamaIndex to efficiently parse and represent files for efficient retrieval and context augmentation using LlamaIndex frameworks.\n", - "
\n", + "\n", "External documentation: https://github.com/run-llama/llama_parse" ] }, @@ -1105,11 +1085,10 @@ "#### Parsing the document\n", "\n", "The following block uses the LlamaParse cloud offering. You can learn more and fetch a respective API key for the service [here](https://cloud.llamaindex.ai/parse).\n", - "
\n", + "\n", "Parsing documents with LlamaParse offers an option for two output modes both of which we will explore and compare below\n", "- Text\n", "- Markdown\n", - "
\n", "\n", "**Note: You can skip to the next block if you want to use the pre-existing parsed version.**" ] diff --git a/notebooks/guides/Fueling_Generative_Content_with_Keyword_Research.ipynb b/notebooks/guides/Fueling_Generative_Content_with_Keyword_Research.ipynb index 3c45e59b..08d2dc86 100644 --- a/notebooks/guides/Fueling_Generative_Content_with_Keyword_Research.ipynb +++ b/notebooks/guides/Fueling_Generative_Content_with_Keyword_Research.ipynb @@ -1,1071 +1,1063 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - " \"Open\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "5HkhthoeyQnV" - }, - "source": [ - "# Fueling Generative Content with Keyword Research\n", - "\n", - "Generative models have proven extremely useful in content idea generation. But they don’t take into account user search demand and trends. In this notebook, let’s see how we can solve that by adding keyword research into the equation.\n", - "\n", - "Read the accompanying [blog post here](https://txt.cohere.ai/generative-content-keyword-research/)." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# Install packages\n", - "! pip install cohere -q" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + " \"Open\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5HkhthoeyQnV" + }, + "source": [ + "# Fueling Generative Content with Keyword Research\n", + "\n", + "Generative models have proven extremely useful in content idea generation. But they don’t take into account user search demand and trends. In this notebook, let’s see how we can solve that by adding keyword research into the equation.\n", + "\n", + "Read the accompanying [blog post here](https://txt.cohere.ai/generative-content-keyword-research/)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Install packages\n", + "! pip install cohere -q" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "4awUCb_3jw-v", + "outputId": "ab8e8e13-99a8-47fc-8736-49a698476075" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "4awUCb_3jw-v", - "outputId": "ab8e8e13-99a8-47fc-8736-49a698476075" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "import cohere\n", - "import numpy as np\n", - "import pandas as pd\n", - "from sklearn.cluster import KMeans\n", - "\n", - "import cohere\n", - "co = cohere.Client(\"COHERE_API_KEY\") # Get your API key: https://dashboard.cohere.com/api-keys" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "#@title Enable text wrapping in Google Colab\n", - "\n", - "from IPython.display import HTML, display\n", - "\n", - "def set_css():\n", - " display(HTML('''\n", - " \n", - " '''))\n", - "get_ipython().events.register('pre_run_cell', set_css)" + "text/plain": [ + "" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import cohere\n", + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn.cluster import KMeans\n", + "\n", + "import cohere\n", + "co = cohere.Client(\"COHERE_API_KEY\") # Get your API key: https://dashboard.cohere.com/api-keys" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#@title Enable text wrapping in Google Colab\n", + "\n", + "from IPython.display import HTML, display\n", + "\n", + "def set_css():\n", + " display(HTML('''\n", + " \n", + " '''))\n", + "get_ipython().events.register('pre_run_cell', set_css)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9YsKrQFsyZIE" + }, + "source": [ + "# Step 1: Get a list of High-performing Keywords " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, we need to get a supply of high-traffic keywords for a given topic. We can get this via keyword research tools, of which are many available. We’ll use Google Keyword Planner, which is free to use." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "9YsKrQFsyZIE" - }, - "source": [ - "# Step 1: Get a list of High-performing Keywords " + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, we need to get a supply of high-traffic keywords for a given topic. We can get this via keyword research tools, of which are many available. We’ll use Google Keyword Planner, which is free to use." + "data": { + "text/plain": [ + "'remote_teams.csv'" ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Download the pre-created dataset (feel free to replace with your CSV file, containing two columns - \"keyword\" and \"volume\")\n", + "\n", + "import wget\n", + "wget.download(\"https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/remote_teams.csv\", \"remote_teams.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 }, + "id": "_JdLS_FVyjfr", + "outputId": "211c8b07-da89-4269-a652-2c164d09338d" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "'remote_teams.csv'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Download the pre-created dataset (feel free to replace with your CSV file, containing two columns - \"keyword\" and \"volume\")\n", - "\n", - "import wget\n", - "wget.download(\"https://raw.githubusercontent.com/cohere-ai/notebooks/main/notebooks/data/remote_teams.csv\", \"remote_teams.csv\")" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 206 - }, - "id": "_JdLS_FVyjfr", - "outputId": "211c8b07-da89-4269-a652-2c164d09338d" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "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", - "
keywordvolume
0managing remote teams1000
1remote teams390
2collaboration tools for remote teams320
3online games for remote teams320
4how to manage remote teams260
\n", - "
" - ], - "text/plain": [ - " keyword volume\n", - "0 managing remote teams 1000\n", - "1 remote teams 390\n", - "2 collaboration tools for remote teams 320\n", - "3 online games for remote teams 320\n", - "4 how to manage remote teams 260" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } + "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", + "
keywordvolume
0managing remote teams1000
1remote teams390
2collaboration tools for remote teams320
3online games for remote teams320
4how to manage remote teams260
\n", + "
" ], - "source": [ - "# Create a dataframe\n", - "df = pd.read_csv('remote_teams.csv')\n", - "df.columns = [\"keyword\",\"volume\"]\n", - "df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "whqG2M2Dylxu" - }, - "source": [ - "# Step 2: Group the Keywords into Topics " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We now have a list of keywords, but this list is still raw. For example, “managing remote teams” is the top-ranking keyword in this list. But at the same time, there are many similar keywords further down in the list, such as “how to effectively manage remote teams.”\n", - "\n", - "We can do that by clustering them into topics. For this, we’ll leverage Cohere’s Embed endpoint and scikit-learn." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "qJbbahQA0BJb" - }, - "source": [ - "### Embed the Keywords with Cohere Embed" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Cohere Embed endpoint turns a text input into a text embedding." + "text/plain": [ + " keyword volume\n", + "0 managing remote teams 1000\n", + "1 remote teams 390\n", + "2 collaboration tools for remote teams 320\n", + "3 online games for remote teams 320\n", + "4 how to manage remote teams 260" ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Create a dataframe\n", + "df = pd.read_csv('remote_teams.csv')\n", + "df.columns = [\"keyword\",\"volume\"]\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "whqG2M2Dylxu" + }, + "source": [ + "# Step 2: Group the Keywords into Topics " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now have a list of keywords, but this list is still raw. For example, “managing remote teams” is the top-ranking keyword in this list. But at the same time, there are many similar keywords further down in the list, such as “how to effectively manage remote teams.”\n", + "\n", + "We can do that by clustering them into topics. For this, we’ll leverage Cohere’s Embed endpoint and scikit-learn." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qJbbahQA0BJb" + }, + "source": [ + "### Embed the Keywords with Cohere Embed" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Cohere Embed endpoint turns a text input into a text embedding." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "O7vz9gkXjGMI", + "outputId": "d7f53d3d-e426-4433-a5be-1bb9c7d2b566" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "O7vz9gkXjGMI", - "outputId": "d7f53d3d-e426-4433-a5be-1bb9c7d2b566" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "def embed_text(texts):\n", - " output = co.embed(\n", - " texts=texts,\n", - " model='embed-english-v3.0',\n", - " input_type=\"search_document\",\n", - " )\n", - " return output.embeddings\n", - "\n", - "embeds = np.array(embed_text(df['keyword'].tolist()))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "GKnEI1E40Djn" - }, - "source": [ - "### Cluster the Keywords into Topics with scikit-learn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We then use these embeddings to cluster the keywords. A common term used for this exercise is “topic modeling.” Here, we can leverage scikit-learn’s KMeans module, a machine learning algorithm for clustering." + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def embed_text(texts):\n", + " output = co.embed(\n", + " texts=texts,\n", + " model='embed-english-v3.0',\n", + " input_type=\"search_document\",\n", + " )\n", + " return output.embeddings\n", + "\n", + "embeds = np.array(embed_text(df['keyword'].tolist()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GKnEI1E40Djn" + }, + "source": [ + "### Cluster the Keywords into Topics with scikit-learn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We then use these embeddings to cluster the keywords. A common term used for this exercise is “topic modeling.” Here, we can leverage scikit-learn’s KMeans module, a machine learning algorithm for clustering." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 }, + "id": "jUAZueb0luKN", + "outputId": "b05799e5-665d-4dcf-fb30-7eb7df1ed03f" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 206 - }, - "id": "jUAZueb0luKN", - "outputId": "b05799e5-665d-4dcf-fb30-7eb7df1ed03f" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
keywordvolumetopic
0managing remote teams10000
1remote teams3901
2collaboration tools for remote teams3201
3online games for remote teams3203
4how to manage remote teams2600
\n", - "
" - ], - "text/plain": [ - " keyword volume topic\n", - "0 managing remote teams 1000 0\n", - "1 remote teams 390 1\n", - "2 collaboration tools for remote teams 320 1\n", - "3 online games for remote teams 320 3\n", - "4 how to manage remote teams 260 0" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "NUM_TOPICS = 4\n", - "kmeans = KMeans(n_clusters=NUM_TOPICS, random_state=21, n_init=\"auto\").fit(embeds)\n", - "df['topic'] = list(kmeans.labels_)\n", - "df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "fLUzQoJD0IdY" - }, - "source": [ - "### Generate Topic Names with Cohere Chat" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We use the Chat to generate a topic name for that cluster." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keywordvolumetopic
0managing remote teams10000
1remote teams3901
2collaboration tools for remote teams3201
3online games for remote teams3203
4how to manage remote teams2600
\n", + "
" ], - "source": [ - "# Group the DataFrame by 'topic' and aggregate the 'keyword' column into sets (which automatically removes duplicates)\n", - "topic_keywords_dict = {topic: list(set(group['keyword'])) for topic, group in df.groupby('topic')}" + "text/plain": [ + " keyword volume topic\n", + "0 managing remote teams 1000 0\n", + "1 remote teams 390 1\n", + "2 collaboration tools for remote teams 320 1\n", + "3 online games for remote teams 320 3\n", + "4 how to manage remote teams 260 0" ] - }, + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "NUM_TOPICS = 4\n", + "kmeans = KMeans(n_clusters=NUM_TOPICS, random_state=21, n_init=\"auto\").fit(embeds)\n", + "df['topic'] = list(kmeans.labels_)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fLUzQoJD0IdY" + }, + "source": [ + "### Generate Topic Names with Cohere Chat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We use the Chat to generate a topic name for that cluster." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Function to generate a topic name based on keywords\n", - "def generate_topic_name(keywords):\n", - " # Construct the prompt\n", - " prompt = f\"\"\"Generate a concise topic name that best represents these keywords.\\\n", - "Provide just the topic name and not any additional details.\n", - "\n", - "Keywords: {', '.join(keywords)}\"\"\"\n", - " \n", - " # Call the Cohere API\n", - " response = co.chat(\n", - " model='command-r', # Choose the model size\n", - " message=prompt,\n", - " preamble=\"\")\n", - " \n", - " # Return the generated text\n", - " return response.text" + "text/plain": [ + "" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Group the DataFrame by 'topic' and aggregate the 'keyword' column into sets (which automatically removes duplicates)\n", + "topic_keywords_dict = {topic: list(set(group['keyword'])) for topic, group in df.groupby('topic')}" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
keywordvolumetopictopic_name
0managing remote teams10000Remote Team Management
1remote teams3901Remote Team Tools and Tips
2collaboration tools for remote teams3201Remote Team Tools and Tips
3online games for remote teams3203Remote Team Fun
4how to manage remote teams2600Remote Team Management
\n", - "
" - ], - "text/plain": [ - " keyword volume topic \\\n", - "0 managing remote teams 1000 0 \n", - "1 remote teams 390 1 \n", - "2 collaboration tools for remote teams 320 1 \n", - "3 online games for remote teams 320 3 \n", - "4 how to manage remote teams 260 0 \n", - "\n", - " topic_name \n", - "0 Remote Team Management \n", - "1 Remote Team Tools and Tips \n", - "2 Remote Team Tools and Tips \n", - "3 Remote Team Fun \n", - "4 Remote Team Management " - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Generate topic names and create a mapping of topic number to topic name\n", - "topic_name_mapping = {topic: generate_topic_name(keywords) for topic, keywords in topic_keywords_dict.items()}\n", - "\n", - "# Use the mapping to create a new column in the DataFrame\n", - "df['topic_name'] = df['topic'].map(topic_name_mapping)\n", - "\n", - "# Display the first few rows to verify the new column\n", - "df.head()" + "text/plain": [ + "" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Function to generate a topic name based on keywords\n", + "def generate_topic_name(keywords):\n", + " # Construct the prompt\n", + " prompt = f\"\"\"Generate a concise topic name that best represents these keywords.\\\n", + "Provide just the topic name and not any additional details.\n", + "\n", + "Keywords: {', '.join(keywords)}\"\"\"\n", + " \n", + " # Call the Cohere API\n", + " response = co.chat(\n", + " model='command-r', # Choose the model size\n", + " message=prompt,\n", + " preamble=\"\")\n", + " \n", + " # Return the generated text\n", + " return response.text" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Topic 0: Remote Team Management\n", - "Topic 1: Remote Team Tools and Tips\n", - "Topic 2: Remote Team Resources\n", - "Topic 3: Remote Team Fun\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# View the list of topics\n", - "for topic, name in topic_name_mapping.items():\n", - " print(f\"Topic {topic}: {name}\")" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "pMQzL5sL0YNN" - }, - "source": [ - "# Step 3: Generate Blog Post Ideas for Each Topic" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that we have the keywords nicely grouped into topics, we can proceed to generate the content ideas.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "1tlIS2db0fWU" - }, - "source": [ - "### Take the Top Keywords from Each Topic" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we can implement a filter to take just the top N keywords from each topic, sorted by the search volume. In our case, we use 10." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "1bnYoTUCGQTv", - "outputId": "cabdd711-641f-44e7-b7c5-19bf85f2512c" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
keywordvolumetopictopic_name
0managing remote teams10000Remote Team Management
1remote teams3901Remote Team Tools and Tips
2collaboration tools for remote teams3201Remote Team Tools and Tips
3online games for remote teams3203Remote Team Fun
4how to manage remote teams2600Remote Team Management
\n", + "
" ], - "source": [ - "TOP_N = 10\n", - "\n", - "# Group the DataFrame by topic and select the top N keywords sorted by volume\n", - "top_keywords = (df.groupby('topic')\n", - " .apply(lambda x: x.nlargest(TOP_N, 'volume'))\n", - " .reset_index(drop=True))\n", - "\n", - "\n", - "# Convert the DataFrame to a nested dictionary\n", - "content_by_topic = {}\n", - "for topic, group in top_keywords.groupby('topic'):\n", - " keywords = ', '.join(list(group['keyword']))\n", - " topic2name = topic2name = dict(df.groupby('topic')['topic_name'].first())\n", - " topic_name = topic2name[topic]\n", - " content_by_topic[topic] = {'topic_name': topic_name, 'keywords': keywords}" + "text/plain": [ + " keyword volume topic \\\n", + "0 managing remote teams 1000 0 \n", + "1 remote teams 390 1 \n", + "2 collaboration tools for remote teams 320 1 \n", + "3 online games for remote teams 320 3 \n", + "4 how to manage remote teams 260 0 \n", + "\n", + " topic_name \n", + "0 Remote Team Management \n", + "1 Remote Team Tools and Tips \n", + "2 Remote Team Tools and Tips \n", + "3 Remote Team Fun \n", + "4 Remote Team Management " ] - }, + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Generate topic names and create a mapping of topic number to topic name\n", + "topic_name_mapping = {topic: generate_topic_name(keywords) for topic, keywords in topic_keywords_dict.items()}\n", + "\n", + "# Use the mapping to create a new column in the DataFrame\n", + "df['topic_name'] = df['topic'].map(topic_name_mapping)\n", + "\n", + "# Display the first few rows to verify the new column\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 285 - }, - "id": "erNJQT3a5kkD", - "outputId": "f8b0c153-0bc9-46bd-b7fe-e5d0283dc3ab" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "{0: {'topic_name': 'Remote Team Management',\n", - " 'keywords': 'managing remote teams, how to manage remote teams, leading remote teams, managing remote teams best practices, remote teams best practices, best practices for managing remote teams, manage remote teams, building culture in remote teams, culture building for remote teams, managing remote teams training'},\n", - " 1: {'topic_name': 'Remote Team Tools and Tips',\n", - " 'keywords': 'remote teams, collaboration tools for remote teams, team building for remote teams, scrum remote teams, tools for remote teams, zapier remote teams, working agreements for remote teams, working with remote teams, free collaboration tools for remote teams, free retrospective tools for remote teams'},\n", - " 2: {'topic_name': 'Remote Team Resources',\n", - " 'keywords': 'best collaboration tools for remote teams, slack best practices for remote teams, best communication tools for remote teams, best tools for remote teams, always on video for remote teams, best apps for remote teams, best free collaboration tools for remote teams, best games for remote teams, best gifts for remote teams, best ice breaker questions for remote teams'},\n", - " 3: {'topic_name': 'Remote Team Fun',\n", - " 'keywords': 'online games for remote teams, team building activities for remote teams, games for remote teams, retrospective ideas for remote teams, team building ideas for remote teams, fun retrospective ideas for remote teams, retro ideas for remote teams, team building exercises for remote teams, trust building exercises for remote teams, activities for remote teams'}}" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Print the topics and they top keywords\n", - "content_by_topic" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "VCXY5cNj0qAW" - }, - "source": [ - "### Create a Prompt with These Keywords" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Topic 0: Remote Team Management\n", + "Topic 1: Remote Team Tools and Tips\n", + "Topic 2: Remote Team Resources\n", + "Topic 3: Remote Team Fun\n" + ] + } + ], + "source": [ + "# View the list of topics\n", + "for topic, name in topic_name_mapping.items():\n", + " print(f\"Topic {topic}: {name}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pMQzL5sL0YNN" + }, + "source": [ + "# Step 3: Generate Blog Post Ideas for Each Topic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have the keywords nicely grouped into topics, we can proceed to generate the content ideas.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1tlIS2db0fWU" + }, + "source": [ + "### Take the Top Keywords from Each Topic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we can implement a filter to take just the top N keywords from each topic, sorted by the search volume. In our case, we use 10." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "1bnYoTUCGQTv", + "outputId": "cabdd711-641f-44e7-b7c5-19bf85f2512c" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we use the Chat endpoint to produce the content ideas. The prompt we’ll use is as follows" + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "TOP_N = 10\n", + "\n", + "# Group the DataFrame by topic and select the top N keywords sorted by volume\n", + "top_keywords = (df.groupby('topic')\n", + " .apply(lambda x: x.nlargest(TOP_N, 'volume'))\n", + " .reset_index(drop=True))\n", + "\n", + "\n", + "# Convert the DataFrame to a nested dictionary\n", + "content_by_topic = {}\n", + "for topic, group in top_keywords.groupby('topic'):\n", + " keywords = ', '.join(list(group['keyword']))\n", + " topic2name = topic2name = dict(df.groupby('topic')['topic_name'].first())\n", + " topic_name = topic2name[topic]\n", + " content_by_topic[topic] = {'topic_name': topic_name, 'keywords': keywords}" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 285 }, + "id": "erNJQT3a5kkD", + "outputId": "f8b0c153-0bc9-46bd-b7fe-e5d0283dc3ab" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "M-g_FiA6fX2w", - "outputId": "d4545e7c-ca43-4b58-ac87-2f2c4227eadc" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "def generate_blog_ideas(keywords):\n", - " prompt = f\"\"\"{keywords}\\n\\nThe above is a list of high-traffic keywords obtained from a keyword research tool. \n", - "Suggest three blog post ideas that are highly relevant to these keywords. \n", - "For each idea, write a one paragraph abstract about the topic. \n", - "Use this format:\n", - "Blog title: \n", - "Abstract: \"\"\"\n", - " \n", - " response = co.chat(\n", - " model='command-r',\n", - " message = prompt)\n", - " return response.text\n" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "metadata": { - "id": "wTV6GG8i0tdK" - }, - "source": [ - "### Generate Content Ideas" + "data": { + "text/plain": [ + "{0: {'topic_name': 'Remote Team Management',\n", + " 'keywords': 'managing remote teams, how to manage remote teams, leading remote teams, managing remote teams best practices, remote teams best practices, best practices for managing remote teams, manage remote teams, building culture in remote teams, culture building for remote teams, managing remote teams training'},\n", + " 1: {'topic_name': 'Remote Team Tools and Tips',\n", + " 'keywords': 'remote teams, collaboration tools for remote teams, team building for remote teams, scrum remote teams, tools for remote teams, zapier remote teams, working agreements for remote teams, working with remote teams, free collaboration tools for remote teams, free retrospective tools for remote teams'},\n", + " 2: {'topic_name': 'Remote Team Resources',\n", + " 'keywords': 'best collaboration tools for remote teams, slack best practices for remote teams, best communication tools for remote teams, best tools for remote teams, always on video for remote teams, best apps for remote teams, best free collaboration tools for remote teams, best games for remote teams, best gifts for remote teams, best ice breaker questions for remote teams'},\n", + " 3: {'topic_name': 'Remote Team Fun',\n", + " 'keywords': 'online games for remote teams, team building activities for remote teams, games for remote teams, retrospective ideas for remote teams, team building ideas for remote teams, fun retrospective ideas for remote teams, retro ideas for remote teams, team building exercises for remote teams, trust building exercises for remote teams, activities for remote teams'}}" ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Print the topics and they top keywords\n", + "content_by_topic" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VCXY5cNj0qAW" + }, + "source": [ + "### Create a Prompt with These Keywords" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we use the Chat endpoint to produce the content ideas. The prompt we’ll use is as follows" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17 }, + "id": "M-g_FiA6fX2w", + "outputId": "d4545e7c-ca43-4b58-ac87-2f2c4227eadc" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we generate the blog post ideas. It takes in a string of keywords, calls the Chat endpoint, and returns the generated text." + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def generate_blog_ideas(keywords):\n", + " prompt = f\"\"\"{keywords}\\n\\nThe above is a list of high-traffic keywords obtained from a keyword research tool. \n", + "Suggest three blog post ideas that are highly relevant to these keywords. \n", + "For each idea, write a one paragraph abstract about the topic. \n", + "Use this format:\n", + "Blog title: \n", + "Abstract: \"\"\"\n", + " \n", + " response = co.chat(\n", + " model='command-r',\n", + " message = prompt)\n", + " return response.text\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wTV6GG8i0tdK" + }, + "source": [ + "### Generate Content Ideas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we generate the blog post ideas. It takes in a string of keywords, calls the Chat endpoint, and returns the generated text." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 }, + "id": "-qGuVkIfmJ_d", + "outputId": "5b7588cb-cfda-4590-80ca-532fceb6f125" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "-qGuVkIfmJ_d", - "outputId": "5b7588cb-cfda-4590-80ca-532fceb6f125" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Topic Name: Remote Team Management\n", - "\n", - "Top Keywords: managing remote teams, how to manage remote teams, leading remote teams, managing remote teams best practices, remote teams best practices, best practices for managing remote teams, manage remote teams, building culture in remote teams, culture building for remote teams, managing remote teams training\n", - "\n", - "Blog Post Ideas: Here are three blog post ideas:\n", - "\n", - "1. Blog title: \"Leading Remote Teams: Strategies for Effective Management\"\n", - " Abstract: Effective management of remote teams is crucial for success, but it comes with unique challenges. This blog will explore practical strategies for leading dispersed employees, focusing on building a cohesive and productive virtual workforce. It will cover topics such as establishing clear communication protocols, fostering a collaborative environment, and the importance of trusting and empowering your remote employees for enhanced performance.\n", - "\n", - "2. Blog title: \"Remote Teams' Best Practices: Creating a Vibrant and Engaging Culture\"\n", - " Abstract: Building a rich culture in a remote team setting is essential for employee engagement and retention. The blog will delve into creative ways to foster a sense of community and connection among team members who may be scattered across the globe. It will offer practical tips on creating virtual rituals, fostering open communication, and harnessing the power of technology for cultural development, ensuring remote employees feel valued and engaged.\n", - "\n", - "3. Blog title: \"Managing Remote Teams: A Comprehensive Guide to Training and Development\"\n", - " Abstract: Training and developing remote teams present specific challenges and opportunities. This comprehensive guide will arm managers with techniques to enhance their remote team's skills and knowledge. It will explore the latest tools and methodologies for remote training, including virtual workshops, e-learning platforms, and performance coaching. Additionally, the blog will discuss the significance of ongoing development and how to create an environment that encourages self-improvement and learning.\n", - "\n", - "Each of these topics explores a specific aspect of managing remote teams, providing valuable insights and practical guidance for leaders and managers in the evolving remote work landscape.\n", - "\n", - "--------------------------------------------------\n", - "Topic Name: Remote Team Tools and Tips\n", - "\n", - "Top Keywords: remote teams, collaboration tools for remote teams, team building for remote teams, scrum remote teams, tools for remote teams, zapier remote teams, working agreements for remote teams, working with remote teams, free collaboration tools for remote teams, free retrospective tools for remote teams\n", - "\n", - "Blog Post Ideas: 1. Blog title: \"The Ultimate Guide to Building Effective Remote Teams\"\n", - " Abstract: Building a cohesive and productive remote team can be challenging. This blog will serve as a comprehensive guide, offering practical tips and insights on how to create a united and successful virtual workforce. It will cover essential topics such as building a strong team culture, utilizing collaboration tools, and fostering effective communication strategies, ensuring remote teams can thrive and achieve their full potential.\n", - "\n", - "2. Blog title: \"The Best Collaboration Tools for Remote Teams: A Comprehensive Review\"\n", - " Abstract: With the rapid rise of remote work, collaboration tools have become essential for teams' productivity and efficiency. This blog aims to review and compare the most popular collaboration tools, providing an in-depth analysis of their features, ease of use, and benefits. It will offer insights into choosing the right tools for remote collaboration, helping teams streamline their workflows and enhance their overall performance.\n", - "\n", - "3. Blog title: \"Remote Retrospective: A Guide to Reflect and Grow as a Remote Team\"\n", - " Abstract: Conducting effective retrospectives is crucial for remote teams to reflect on their experiences, learn from the past, and chart a course for the future. This blog will focus on remote retrospectives, exploring different formats, techniques, and free tools that teams can use to foster continuous improvement. It will also provide tips on creating a safe and inclusive environment, encouraging honest feedback and productive discussions.\n", - "\n", - "--------------------------------------------------\n", - "Topic Name: Remote Team Resources\n", - "\n", - "Top Keywords: best collaboration tools for remote teams, slack best practices for remote teams, best communication tools for remote teams, best tools for remote teams, always on video for remote teams, best apps for remote teams, best free collaboration tools for remote teams, best games for remote teams, best gifts for remote teams, best ice breaker questions for remote teams\n", - "\n", - "Blog Post Ideas: 1. Blog title: \"The Ultimate Guide to Remote Team Collaboration Tools\"\n", - " Abstract: With the rise of remote work, choosing the right collaboration tools can be crucial to a team's success and productivity. This blog aims to be an comprehensive guide, outlining the various types of tools available, from communication platforms like Slack to project management software and online collaboration tools. It will offer best practices and guidelines for selecting and utilizing these tools, ensuring remote teams can work seamlessly together and maximize their output.\n", - "\n", - "2. Blog title: \"Remote Team Management: Tips for Leading a Successful Virtual Workforce\"\n", - " Abstract: Managing a remote team comes with its own set of challenges. This blog will provide an in-depth exploration of best practices for leading and motivating virtual teams. Covering topics such as effective communication strategies, performance evaluation, and maintaining a cohesive team culture, it will offer practical tips for managers and leaders to ensure their remote teams are engaged, productive, and well-managed.\n", - "\n", - "3. Blog title: \"The Fun Side of Remote Work: Games, Icebreakers, and Team Building Activities\"\n", - " Abstract: Remote work can be isolating, and this blog aims to provide some fun and creative solutions. It will offer a comprehensive guide to the best online games, icebreaker questions, and virtual team building activities that remote teams can use to connect and bond. From virtual escape rooms to interactive games and thought-provoking icebreakers, these ideas will help enhance team spirit, foster collaboration, and create a enjoyable remote work experience.\n", - "\n", - "--------------------------------------------------\n", - "Topic Name: Remote Team Fun\n", - "\n", - "Top Keywords: online games for remote teams, team building activities for remote teams, games for remote teams, retrospective ideas for remote teams, team building ideas for remote teams, fun retrospective ideas for remote teams, retro ideas for remote teams, team building exercises for remote teams, trust building exercises for remote teams, activities for remote teams\n", - "\n", - "Blog Post Ideas: 1. Blog title: \"The Great Remote Retro: Fun Games and Activities for Your Team\"\n", - " Abstract: Remote work can make team building challenging. This blog post will be a fun guide to hosting interactive retro games and activities that bring your remote team together. From online escape rooms to virtual scavenger hunts, we'll explore the best ways to engage and unite your team, fostering collaboration and camaraderie. Virtual icebreakers and retrospective ideas will also be included to make your remote meetings more interactive and enjoyable.\n", - "\n", - "2. Blog title: \"Trust Falls: Building Trust Among Remote Teams\"\n", - " Abstract: Trust is the foundation of every successful team, but how do you build it when everyone is scattered across different locations? This blog will focus on trust-building exercises and activities designed specifically for remote teams. From virtual trust falls to transparent communication practices, we'll discover innovative ways to strengthen team bonds and foster a culture of trust. You'll learn how to create an environment where your remote team can thrive and collaborate effectively.\n", - "\n", - "3. Blog title: \"Game Night for Remote Teams: A Guide to Online Games and Activities\"\n", - " Abstract: Miss the old office game nights? This blog will bring the fun back with a guide to hosting online game nights and activities that are perfect for remote teams. From trivia games to virtual board games and even remote-friendly outdoor adventures, we'll keep your team engaged and entertained. With tips on setting up online tournaments and ideas for encouraging participation, your virtual game nights will be the highlight of your team's week. Keep your remote team spirit high!\n", - "\n", - "--------------------------------------------------\n" - ] - } + "data": { + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "# Generate content ideas\n", - "for key,value in content_by_topic.items():\n", - " value['ideas'] = generate_blog_ideas(value['keywords'])\n", - "\n", - "\n", - "# Print the results\n", - "for key,value in content_by_topic.items():\n", - " print(f\"Topic Name: {value['topic_name']}\\n\")\n", - " print(f\"Top Keywords: {value['keywords']}\\n\")\n", - " print(f\"Blog Post Ideas: {value['ideas']}\\n\")\n", - " print(\"-\"*50)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Anr0Hu3hLxE3" - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "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.4" + "name": "stdout", + "output_type": "stream", + "text": [ + "Topic Name: Remote Team Management\n", + "\n", + "Top Keywords: managing remote teams, how to manage remote teams, leading remote teams, managing remote teams best practices, remote teams best practices, best practices for managing remote teams, manage remote teams, building culture in remote teams, culture building for remote teams, managing remote teams training\n", + "\n", + "Blog Post Ideas: Here are three blog post ideas:\n", + "\n", + "1. Blog title: \"Leading Remote Teams: Strategies for Effective Management\"\n", + " Abstract: Effective management of remote teams is crucial for success, but it comes with unique challenges. This blog will explore practical strategies for leading dispersed employees, focusing on building a cohesive and productive virtual workforce. It will cover topics such as establishing clear communication protocols, fostering a collaborative environment, and the importance of trusting and empowering your remote employees for enhanced performance.\n", + "\n", + "2. Blog title: \"Remote Teams' Best Practices: Creating a Vibrant and Engaging Culture\"\n", + " Abstract: Building a rich culture in a remote team setting is essential for employee engagement and retention. The blog will delve into creative ways to foster a sense of community and connection among team members who may be scattered across the globe. It will offer practical tips on creating virtual rituals, fostering open communication, and harnessing the power of technology for cultural development, ensuring remote employees feel valued and engaged.\n", + "\n", + "3. Blog title: \"Managing Remote Teams: A Comprehensive Guide to Training and Development\"\n", + " Abstract: Training and developing remote teams present specific challenges and opportunities. This comprehensive guide will arm managers with techniques to enhance their remote team's skills and knowledge. It will explore the latest tools and methodologies for remote training, including virtual workshops, e-learning platforms, and performance coaching. Additionally, the blog will discuss the significance of ongoing development and how to create an environment that encourages self-improvement and learning.\n", + "\n", + "Each of these topics explores a specific aspect of managing remote teams, providing valuable insights and practical guidance for leaders and managers in the evolving remote work landscape.\n", + "\n", + "--------------------------------------------------\n", + "Topic Name: Remote Team Tools and Tips\n", + "\n", + "Top Keywords: remote teams, collaboration tools for remote teams, team building for remote teams, scrum remote teams, tools for remote teams, zapier remote teams, working agreements for remote teams, working with remote teams, free collaboration tools for remote teams, free retrospective tools for remote teams\n", + "\n", + "Blog Post Ideas: 1. Blog title: \"The Ultimate Guide to Building Effective Remote Teams\"\n", + " Abstract: Building a cohesive and productive remote team can be challenging. This blog will serve as a comprehensive guide, offering practical tips and insights on how to create a united and successful virtual workforce. It will cover essential topics such as building a strong team culture, utilizing collaboration tools, and fostering effective communication strategies, ensuring remote teams can thrive and achieve their full potential.\n", + "\n", + "2. Blog title: \"The Best Collaboration Tools for Remote Teams: A Comprehensive Review\"\n", + " Abstract: With the rapid rise of remote work, collaboration tools have become essential for teams' productivity and efficiency. This blog aims to review and compare the most popular collaboration tools, providing an in-depth analysis of their features, ease of use, and benefits. It will offer insights into choosing the right tools for remote collaboration, helping teams streamline their workflows and enhance their overall performance.\n", + "\n", + "3. Blog title: \"Remote Retrospective: A Guide to Reflect and Grow as a Remote Team\"\n", + " Abstract: Conducting effective retrospectives is crucial for remote teams to reflect on their experiences, learn from the past, and chart a course for the future. This blog will focus on remote retrospectives, exploring different formats, techniques, and free tools that teams can use to foster continuous improvement. It will also provide tips on creating a safe and inclusive environment, encouraging honest feedback and productive discussions.\n", + "\n", + "--------------------------------------------------\n", + "Topic Name: Remote Team Resources\n", + "\n", + "Top Keywords: best collaboration tools for remote teams, slack best practices for remote teams, best communication tools for remote teams, best tools for remote teams, always on video for remote teams, best apps for remote teams, best free collaboration tools for remote teams, best games for remote teams, best gifts for remote teams, best ice breaker questions for remote teams\n", + "\n", + "Blog Post Ideas: 1. Blog title: \"The Ultimate Guide to Remote Team Collaboration Tools\"\n", + " Abstract: With the rise of remote work, choosing the right collaboration tools can be crucial to a team's success and productivity. This blog aims to be an comprehensive guide, outlining the various types of tools available, from communication platforms like Slack to project management software and online collaboration tools. It will offer best practices and guidelines for selecting and utilizing these tools, ensuring remote teams can work seamlessly together and maximize their output.\n", + "\n", + "2. Blog title: \"Remote Team Management: Tips for Leading a Successful Virtual Workforce\"\n", + " Abstract: Managing a remote team comes with its own set of challenges. This blog will provide an in-depth exploration of best practices for leading and motivating virtual teams. Covering topics such as effective communication strategies, performance evaluation, and maintaining a cohesive team culture, it will offer practical tips for managers and leaders to ensure their remote teams are engaged, productive, and well-managed.\n", + "\n", + "3. Blog title: \"The Fun Side of Remote Work: Games, Icebreakers, and Team Building Activities\"\n", + " Abstract: Remote work can be isolating, and this blog aims to provide some fun and creative solutions. It will offer a comprehensive guide to the best online games, icebreaker questions, and virtual team building activities that remote teams can use to connect and bond. From virtual escape rooms to interactive games and thought-provoking icebreakers, these ideas will help enhance team spirit, foster collaboration, and create a enjoyable remote work experience.\n", + "\n", + "--------------------------------------------------\n", + "Topic Name: Remote Team Fun\n", + "\n", + "Top Keywords: online games for remote teams, team building activities for remote teams, games for remote teams, retrospective ideas for remote teams, team building ideas for remote teams, fun retrospective ideas for remote teams, retro ideas for remote teams, team building exercises for remote teams, trust building exercises for remote teams, activities for remote teams\n", + "\n", + "Blog Post Ideas: 1. Blog title: \"The Great Remote Retro: Fun Games and Activities for Your Team\"\n", + " Abstract: Remote work can make team building challenging. This blog post will be a fun guide to hosting interactive retro games and activities that bring your remote team together. From online escape rooms to virtual scavenger hunts, we'll explore the best ways to engage and unite your team, fostering collaboration and camaraderie. Virtual icebreakers and retrospective ideas will also be included to make your remote meetings more interactive and enjoyable.\n", + "\n", + "2. Blog title: \"Trust Falls: Building Trust Among Remote Teams\"\n", + " Abstract: Trust is the foundation of every successful team, but how do you build it when everyone is scattered across different locations? This blog will focus on trust-building exercises and activities designed specifically for remote teams. From virtual trust falls to transparent communication practices, we'll discover innovative ways to strengthen team bonds and foster a culture of trust. You'll learn how to create an environment where your remote team can thrive and collaborate effectively.\n", + "\n", + "3. Blog title: \"Game Night for Remote Teams: A Guide to Online Games and Activities\"\n", + " Abstract: Miss the old office game nights? This blog will bring the fun back with a guide to hosting online game nights and activities that are perfect for remote teams. From trivia games to virtual board games and even remote-friendly outdoor adventures, we'll keep your team engaged and entertained. With tips on setting up online tournaments and ideas for encouraging participation, your virtual game nights will be the highlight of your team's week. Keep your remote team spirit high!\n", + "\n", + "--------------------------------------------------\n" + ] } + ], + "source": [ + "# Generate content ideas\n", + "for key,value in content_by_topic.items():\n", + " value['ideas'] = generate_blog_ideas(value['keywords'])\n", + "\n", + "\n", + "# Print the results\n", + "for key,value in content_by_topic.items():\n", + " print(f\"Topic Name: {value['topic_name']}\\n\")\n", + " print(f\"Top Keywords: {value['keywords']}\\n\")\n", + " print(f\"Blog Post Ideas: {value['ideas']}\\n\")\n", + " print(\"-\"*50)" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/guides/Long_form_General_Strategies.ipynb b/notebooks/guides/Long_form_General_Strategies.ipynb index 0112fdff..5d51d5dc 100644 --- a/notebooks/guides/Long_form_General_Strategies.ipynb +++ b/notebooks/guides/Long_form_General_Strategies.ipynb @@ -1,44 +1,32 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "1CmEDootEpNV" - }, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "metadata": { "id": "_q-7fEZxmIHm" }, "source": [ + "# Long form - general strategies \n", + "\n", "Large Language Models (LLMs) are becoming increasingly capable of comprehending text, among others excelling in document analysis. The new Cohere model, [Command-R](https://huggingface.co/CohereForAI/c4ai-command-r-v01), boasts a context length of 128k, which makes it particularly effective for such tasks. Nevertheless, even with the extended context window, some documents might be too lengthy to accommodate in full.\n", "\n", "In this cookbook, we'll explore techniques to address cases when relevant information doesn't fit in the model context window.\n", "\n", "We'll show you three potential mitigation strategies: truncating the document, query-based retrieval, and a \"text rank\" approach we use internally at Cohere.\n", "\n", - "### Table of content:\n", + "## Table of contents:\n", "1. [Getting started](#getting-started)\n", - "2. [Approach 1: Truncate](#truncate)\n", - "3. [Approach 2: Query Based Retrieval](#query-based-retrieval)\n", - "4. [Approach 3: Text Rank](#text-rank)\n", + "2. [Approach 1: Truncate](#approach-1)\n", + "3. [Approach 2: Query Based Retrieval](#approach-2)\n", + "4. [Approach 3: Text Rank](#approach-3)\n", "\n", - "### Summary\n", + "## Summary\n", "\n", "| Approach | Description | Pros | Cons | When to use? |\n", "|-----------------------|-------------------------------------------|-------------------------------------------|-------------------------------------------|-------------------------------------------|\n", "| Truncation | Truncate the document to fit the context window. | - Simplicity of implementation
(does not rely on extrenal infrastructure)| - Loses information at the end of the document | Utilize when all relevant information is contained
at the beginning of the document. |\n", "| Query Based Retrieval| Utilize semantic similarity to retrieve text chunks
that are most relevant to the query. | - Focuses on sections directly relevant to
the query | - Relies on a semantic similarity algorithm.
- Might lose broader context | Employ when seeking specific
information within the text. |\n", - "| Text Rank | Apply graph theory to generate a cohesive set
of chunks that effectively represent the document. | - Preserves the broader picture. | - Might lose detailed information. | Utilize in summaries and when the question
requires broader context. |\n", - "\n", - "\n", - "\n", - "\n", - "\n" + "| Text Rank | Apply graph theory to generate a cohesive set
of chunks that effectively represent the document. | - Preserves the broader picture. | - Might lose detailed information. | Utilize in summaries and when the question
requires broader context. |" ] }, { @@ -48,253 +36,38 @@ }, "source": [ "\n", - "\n", - "# Getting Started" + "## Getting Started" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "background_save": true, - "base_uri": "https://localhost:8080/" - }, - "id": "wuQ1PO8FadQf", - "outputId": "c6cc36f7-6368-4cdc-ce57-4d95249e409f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting cohere\n", - " Downloading cohere-4.54-py3-none-any.whl (52 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hRequirement already satisfied: aiohttp<4.0,>=3.0 in /usr/local/lib/python3.10/dist-packages (from cohere) (3.9.3)\n", - "Collecting backoff<3.0,>=2.0 (from cohere)\n", - " Downloading backoff-2.2.1-py3-none-any.whl (15 kB)\n", - "Collecting fastavro<2.0,>=1.8 (from cohere)\n", - " Downloading fastavro-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m33.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hCollecting importlib_metadata<7.0,>=6.0 (from cohere)\n", - " Downloading importlib_metadata-6.11.0-py3-none-any.whl (23 kB)\n", - "Requirement already satisfied: requests<3.0.0,>=2.25.0 in /usr/local/lib/python3.10/dist-packages (from cohere) (2.31.0)\n", - "Requirement already satisfied: urllib3<3,>=1.26 in /usr/local/lib/python3.10/dist-packages (from cohere) (2.0.7)\n", - "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (1.3.1)\n", - "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (23.2.0)\n", - "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (1.4.1)\n", - "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (6.0.5)\n", - "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (1.9.4)\n", - "Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0,>=3.0->cohere) (4.0.3)\n", - "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.10/dist-packages (from importlib_metadata<7.0,>=6.0->cohere) (3.17.0)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.25.0->cohere) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.25.0->cohere) (3.6)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.25.0->cohere) (2024.2.2)\n", - "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", - "\u001b[0mTraceback (most recent call last):\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/base_command.py\", line 169, in exc_logging_wrapper\n", - " status = run_func(*args)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/req_command.py\", line 242, in wrapper\n", - " return func(self, options, args)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/commands/install.py\", line 324, in run\n", - " session = self.get_default_session(options)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/req_command.py\", line 98, in get_default_session\n", - " self._session = self.enter_context(self._build_session(options))\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/req_command.py\", line 125, in _build_session\n", - " session = PipSession(\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/network/session.py\", line 342, in __init__\n", - " self.headers[\"User-Agent\"] = user_agent()\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/network/session.py\", line 175, in user_agent\n", - " setuptools_dist = get_default_environment().get_distribution(\"setuptools\")\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/metadata/__init__.py\", line 75, in get_default_environment\n", - " return select_backend().Environment.default()\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/metadata/__init__.py\", line 63, in select_backend\n", - " from . import pkg_resources\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/metadata/pkg_resources.py\", line 8, in \n", - " from pip._vendor import pkg_resources\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 3327, in \n", - " def _initialize_master_working_set():\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 3301, in _call_aside\n", - " f(*args, **kwargs)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 3339, in _initialize_master_working_set\n", - " working_set = WorkingSet._build_master()\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 620, in _build_master\n", - " ws = cls()\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 613, in __init__\n", - " self.add_entry(entry)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 669, in add_entry\n", - " for dist in find_distributions(entry, True):\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 2130, in find_on_path\n", - " for entry in sorted(entries):\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_vendor/pkg_resources/__init__.py\", line 2127, in \n", - " entries = (os.path.join(path_item, child) for child in safe_listdir(path_item))\n", - " File \"/usr/lib/python3.10/posixpath.py\", line 71, in join\n", - " def join(a, *p):\n", - "KeyboardInterrupt\n", - "\n", - "During handling of the above exception, another exception occurred:\n", - "\n", - "Traceback (most recent call last):\n", - " File \"/usr/local/bin/pip3\", line 8, in \n", - " sys.exit(main())\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/main.py\", line 79, in main\n", - " return command.main(cmd_args)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/base_command.py\", line 101, in main\n", - " return self._main(args)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/base_command.py\", line 223, in _main\n", - " return run(options, args)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/cli/base_command.py\", line 206, in exc_logging_wrapper\n", - " logger.critical(\"Operation cancelled by user\")\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 1524, in critical\n", - " self._log(CRITICAL, msg, args, **kwargs)\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 1624, in _log\n", - " self.handle(record)\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 1634, in handle\n", - " self.callHandlers(record)\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 1696, in callHandlers\n", - " hdlr.handle(record)\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 968, in handle\n", - " self.emit(record)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/utils/logging.py\", line 168, in emit\n", - " message = self.format(record)\n", - " File \"/usr/lib/python3.10/logging/__init__.py\", line 943, in format\n", - " return fmt.format(record)\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/utils/logging.py\", line 119, in format\n", - " prefix += \" \" * get_indentation()\n", - " File \"/usr/local/lib/python3.10/dist-packages/pip/_internal/utils/logging.py\", line 69, in get_indentation\n", - " def get_indentation() -> int:\n", - "KeyboardInterrupt\n", - "^C\n", - "Requirement already satisfied: tokenizers in /usr/local/lib/python3.10/dist-packages (0.15.2)\n", - "Requirement already satisfied: huggingface_hub<1.0,>=0.16.4 in /usr/local/lib/python3.10/dist-packages (from tokenizers) (0.20.3)\n", - "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (3.13.1)\n", - "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (2023.6.0)\n", - "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (2.31.0)\n", - "Requirement already satisfied: tqdm>=4.42.1 in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (4.66.2)\n", - "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (6.0.1)\n", - "Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (4.10.0)\n", - "Requirement already satisfied: packaging>=20.9 in /usr/local/lib/python3.10/dist-packages (from huggingface_hub<1.0,>=0.16.4->tokenizers) (23.2)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface_hub<1.0,>=0.16.4->tokenizers) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface_hub<1.0,>=0.16.4->tokenizers) (3.6)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface_hub<1.0,>=0.16.4->tokenizers) (2.0.7)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface_hub<1.0,>=0.16.4->tokenizers) (2024.2.2)\n", - "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", - "\u001b[0mCollecting langchain\n", - " Downloading langchain-0.1.11-py3-none-any.whl (807 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m807.5/807.5 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hRequirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (6.0.1)\n", - "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.0.28)\n", - "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (3.9.3)\n", - "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (4.0.3)\n", - "Collecting dataclasses-json<0.7,>=0.5.7 (from langchain)\n", - " Downloading dataclasses_json-0.6.4-py3-none-any.whl (28 kB)\n", - "Collecting jsonpatch<2.0,>=1.33 (from langchain)\n", - " Downloading jsonpatch-1.33-py2.py3-none-any.whl (12 kB)\n", - "Collecting langchain-community<0.1,>=0.0.25 (from langchain)\n", - " Downloading langchain_community-0.0.27-py3-none-any.whl (1.8 MB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hCollecting langchain-core<0.2,>=0.1.29 (from langchain)\n", - " Downloading langchain_core-0.1.30-py3-none-any.whl (256 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m256.9/256.9 kB\u001b[0m \u001b[31m18.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hCollecting langchain-text-splitters<0.1,>=0.0.1 (from langchain)\n", - " Downloading langchain_text_splitters-0.0.1-py3-none-any.whl (21 kB)\n", - "Collecting langsmith<0.2.0,>=0.1.17 (from langchain)\n", - " Downloading langsmith-0.1.23-py3-none-any.whl (66 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.6/66.6 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hRequirement already satisfied: numpy<2,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.25.2)\n", - "Requirement already satisfied: pydantic<3,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.6.3)\n", - "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.31.0)\n", - "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (8.2.3)\n", - "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n", - "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.2.0)\n", - "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)\n", - "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.5)\n", - "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)\n", - "Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json<0.7,>=0.5.7->langchain)\n", - " Downloading marshmallow-3.21.1-py3-none-any.whl (49 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hCollecting typing-inspect<1,>=0.4.0 (from dataclasses-json<0.7,>=0.5.7->langchain)\n", - " Downloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n", - "Collecting jsonpointer>=1.9 (from jsonpatch<2.0,>=1.33->langchain)\n", - " Downloading jsonpointer-2.4-py2.py3-none-any.whl (7.8 kB)\n", - "Requirement already satisfied: anyio<5,>=3 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.2,>=0.1.29->langchain) (3.7.1)\n", - "Requirement already satisfied: packaging<24.0,>=23.2 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.2,>=0.1.29->langchain) (23.2)\n", - "Collecting orjson<4.0.0,>=3.9.14 (from langsmith<0.2.0,>=0.1.17->langchain)\n", - " Downloading orjson-3.9.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (138 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m138.5/138.5 kB\u001b[0m \u001b[31m15.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hRequirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (0.6.0)\n", - "Requirement already satisfied: pydantic-core==2.16.3 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (2.16.3)\n", - "Requirement already satisfied: typing-extensions>=4.6.1 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (4.10.0)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.6)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2.0.7)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2024.2.2)\n", - "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain) (3.0.3)\n", - "Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3->langchain-core<0.2,>=0.1.29->langchain) (1.3.1)\n", - "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3->langchain-core<0.2,>=0.1.29->langchain) (1.2.0)\n", - "Collecting mypy-extensions>=0.3.0 (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain)\n", - " Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)\n", - "Installing collected packages: orjson, mypy-extensions, marshmallow, jsonpointer, typing-inspect, jsonpatch, langsmith, dataclasses-json, langchain-core, langchain-text-splitters, langchain-community, langchain\n", - "Successfully installed dataclasses-json-0.6.4 jsonpatch-1.33 jsonpointer-2.4 langchain-0.1.11 langchain-community-0.0.27 langchain-core-0.1.30 langchain-text-splitters-0.0.1 langsmith-0.1.23 marshmallow-3.21.1 mypy-extensions-1.0.0 orjson-3.9.15 typing-inspect-0.9.0\n", - "Requirement already satisfied: nltk in /usr/local/lib/python3.10/dist-packages (3.8.1)\n", - "Requirement already satisfied: click in /usr/local/lib/python3.10/dist-packages (from nltk) (8.1.7)\n", - "Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from nltk) (1.3.2)\n", - "Requirement already satisfied: regex>=2021.8.3 in /usr/local/lib/python3.10/dist-packages (from nltk) (2023.12.25)\n", - "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from nltk) (4.66.2)\n", - "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (3.2.1)\n", - "Collecting pypdf2\n", - " Downloading pypdf2-3.0.1-py3-none-any.whl (232 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m232.6/232.6 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hInstalling collected packages: pypdf2\n", - "Successfully installed pypdf2-3.0.1\n" - ] - } - ], + "execution_count": 1, + "metadata": {}, + "outputs": [], "source": [ - "####################################################################################################\n", - "#\n", - "# Uncomment if you need to install the following packages\n", - "#\n", - "####################################################################################################\n", - "# %%capture\n", - "# !pip install cohere\n", - "# !pip install python-dotenv\n", - "# !pip install tokenizers\n", - "# !pip install langchain\n", - "# !pip install nltk\n", - "# !pip install networkx\n", - "# !pip install pypdf2" + "%%capture\n", + "!pip install cohere\n", + "!pip install python-dotenv\n", + "!pip install tokenizers\n", + "!pip install langchain\n", + "!pip install nltk\n", + "!pip install networkx\n", + "!pip install pypdf2" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "UFi1QH3sZUEZ", - "outputId": "3e72afe2-2c60-472e-b838-949676897e13" - }, + "execution_count": 3, + "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "[nltk_data] Downloading package punkt to /root/nltk_data...\n", + "[nltk_data] Downloading package punkt to\n", + "[nltk_data] /home/anna_cohere_com/nltk_data...\n", "[nltk_data] Package punkt is already up-to-date!\n" ] - }, - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ @@ -323,106 +96,7 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 17 - }, - "id": "6BtV3iJ_UQ2w", - "outputId": "76303020-4c08-4f5e-aa5a-03762686455d" - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def set_css():\n", - " display(HTML('''\n", - " \n", - " '''))\n", - "get_ipython().events.register('pre_run_cell', set_css)\n", - "\n", - "set_css()" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -430,15 +104,7 @@ "id": "K603hzyKda2f", "outputId": "611374e9-1e51-4012-c99c-9ecb17a17e19" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter your Cohere API key: ··········\n" - ] - } - ], + "outputs": [], "source": [ "# Set up Cohere client\n", "co_model = 'command-r'\n", @@ -448,7 +114,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "id": "kI0inogLmIHp" }, @@ -501,7 +167,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -511,84 +177,12 @@ "outputId": "bc24d5a7-8bde-4d2a-e569-8a6941612629" }, "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stdout", "output_type": "stream", "text": [ "PDF saved successfully to 'example.pdf'\n", - "Document length - #tokens: 128618\n" + "Document length - #tokens: 134184\n" ] } ], @@ -603,7 +197,7 @@ "long_text = long_text.replace('\\n', ' ')\n", "\n", "# Print the length of the document\n", - "print(\"Document length - #tokens:\", len(co.tokenize(long_text)))" + "print(\"Document length - #tokens:\", len(co.tokenize(text=long_text, model=co_model).tokens))" ] }, { @@ -617,7 +211,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -626,80 +220,7 @@ "id": "PAa9xaU6-8ls", "outputId": "7e60436a-d8a2-42ec-df85-6ae3402bc106" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def generate_response(message, max_tokens=300, temperature=0.2, k=0):\n", " \"\"\"\n", @@ -727,7 +248,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -736,80 +257,7 @@ "id": "80fgeyAhZDZD", "outputId": "3a756564-c6d9-44d6-ac97-ffb8c33d09f6" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Example summary prompt.\n", "prompt_template = \"\"\"\n", @@ -862,8 +310,8 @@ "id": "AH-tKADHmIHq" }, "source": [ - "\n", - "# Approach 1 - Truncate" + "\n", + "## Approach 1 - Truncate" ] }, { @@ -877,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -886,80 +334,7 @@ "id": "JrvVls3smIHq", "outputId": "6ec69e1b-0d6d-4b96-e8ae-650ebc049a7a" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# The new Cohere model has a context limit of 128k tokens. However, for the purpose of this exercise, we will assume a smaller context window.\n", "# Employing a smaller context window also has the additional benefit of reducing the cost per request, especially if billed by the number of tokens.\n", @@ -972,7 +347,7 @@ " This can break up sentences, passages, etc.\n", " \"\"\"\n", "\n", - " tokenized = co.tokenize(long).token_strings\n", + " tokenized = co.tokenize(text=long, model=co_model).token_strings\n", " truncated = tokenized[:max_tokens]\n", " short = \"\".join(truncated)\n", " return short" @@ -980,7 +355,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -990,83 +365,13 @@ "outputId": "0273fe8b-814b-4d5b-8da5-be85bfa9ea45" }, "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stdout", "output_type": "stream", "text": [ - "The document outlines the European Union's proposed Regulation on Artificial Intelligence, aiming to establish harmonised rules for AI development and use while ensuring fundamental rights protection. It defines the scope, purposes, and risks addressed, excluding national security and military purposes. Prohibited AI practices, such as real-time biometric identification in public spaces, are detailed. The regulation proposes a risk-based approach, classifying high-risk AI systems and setting requirements for providers and deployers. It establishes governance structures and obligations for general-purpose AI models, including transparency and copyright compliance. The document also covers issues like conformity assessment, responsibilities along the AI value chain, and standardisation. The regulation aims to foster trustworthy AI while protecting public interests and fundamental rights.\n" + "The document discusses the impact of a specific protein, p53, on the process of angiogenesis, which is the growth of new blood vessels. Angiogenesis plays a critical role in various physiological processes, including wound healing and embryonic development. The presence of the p53 protein can inhibit angiogenesis by regulating the expression of certain genes and proteins. This inhibition can have significant implications for tumor growth, as angiogenesis is essential for tumor progression. Therefore, understanding the role of p53 in angiogenesis can contribute to our knowledge of tumor suppression and potential therapeutic interventions.\n", + "\n", + "Additionally, the document mentions that the regulation of angiogenesis by p53 occurs independently of the protein's role in cell cycle arrest and apoptosis, which are other key functions of p53 in tumor suppression. This suggests that p53 has a complex and multifaceted impact on cellular processes.\n" ] } ], @@ -1083,8 +388,8 @@ "id": "pC1l77odmIHr" }, "source": [ - "\n", - "# Approach 2: Query Based Retrieval\n", + "\n", + "## Approach 2: Query Based Retrieval\n", "\n", "In this section we present how we can leverage a query retriereval based approach to generate an answer to the following question: `Based on the document, are there any risks related to Elon Musk?`.\n", "\n", @@ -1116,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1125,86 +430,8 @@ "id": "XIbGWw2GmIHr", "outputId": "9ca56d31-d7b4-4e48-e9d2-2279f9d2caaf" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "############################################################\n", - "#\n", - "# Utility functions for chunking\n", - "#\n", - "############################################################\n", "def split_text_into_sentences(text) -> List[str]:\n", " \"\"\"\n", " Split the input text into a list of sentences.\n", @@ -1237,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1247,85 +474,13 @@ "outputId": "ae67c468-b5d3-43a4-da36-83a2dc16956a" }, "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stdout", "output_type": "stream", "text": [ - "Example sentence: ['This is to ensure that the deployer is aware and takes them into acc ount when using the high - risk AI system.']\n", + "Example sentence: ['4.']\n", "\n", - "Example passage: ['Notified bodies shall have procedures for the performance of activities which take due account of the size of an undertaking, th e sector in which it operates, its structure, the degree of complexity of the AI system in question. 8. Notified bodies shall take out appropriate liability insurance for their conformity assessment activities, unless liability is assumed by the Member Sta te in which they are established in accordance with national law or that Member State is itself directly responsible for the conformity assessment. 9. Notified bodies shall be capable of carrying out all the tasks falling to them under this Regulation with the highest degree of professional integrity and the requisite competence in the specific field, whether those tasks are carried out by notified bodies themselves or on their behalf and under their responsibility. ']\n" + "Example passage: ['T echnical robustness and safety means that AI systems are developed and used in a way that allows robustness in case of problems and resilience against attempts to alter the use or performance of the AI system so as to allow unlawful use by third parties, a nd minimise unintended harm. Privacy and data governance means that AI systems are developed and used in compliance with existing privacy and data protection rules, while processing data that meets high standards in terms of quality and integrity. Transpar ency means that AI systems are developed and used in a way that allows appropriate traceability and explainability, while making humans aware that they communicate or interact with an AI system, as well as duly informing deployers of the capabilities and l imitations of that AI system and affected persons about their rights. Diversity, non - discrimination and fairness means that AI systems are developed and used in a way that includes diverse actors and promotes equal access, gender equality and cultural dive rsity, while avoiding discriminatory impacts and unfair biases that are prohibited by Union or national law. Social and environmental well - being means that AI systems are developed and used in a sustainable and environmentally friendly manner as well as in a way to benefit all human beings, while monitoring and assessing the long - term impacts on the individual, society and democracy. ']\n" ] } ], @@ -1339,7 +494,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1348,80 +503,7 @@ "id": "w6pjBAA9mIHr", "outputId": "ab3f3ae1-3b38-4999-f8f7-1259d070c88b" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def _add_chunks_by_priority(\n", " chunks: List[str],\n", @@ -1442,7 +524,7 @@ "\n", " while num_tokens < max_tokens and len(idcs_queue) > 0:\n", " next_idx = idcs_queue.popleft()\n", - " num_tokens += co.tokenize(chunks[next_idx]).length\n", + " num_tokens += len(co.tokenize(text=chunks[next_idx], model=co_model).tokens)\n", " # keep index and chunk, to reorder chronologically\n", " selected.append((next_idx, chunks[next_idx]))\n", " if num_tokens > max_tokens:\n", @@ -1465,7 +547,7 @@ " # 2. Use co.rerank to rank chunks vs. query\n", " chunks_reranked = co.rerank(query=query, documents=chunks, model=\"rerank-english-v3.0\")\n", " idcs_sorted_by_relevance = [\n", - " chunk.index for chunk in sorted(chunks_reranked, key=lambda c: c.relevance_score, reverse=True)\n", + " chunk.index for chunk in sorted(chunks_reranked.results, key=lambda c: c.relevance_score, reverse=True)\n", " ]\n", "\n", " # 3. Add chunks back in order of relevance\n", @@ -1479,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1488,80 +570,7 @@ "id": "SX04iD3emIHr", "outputId": "dbe55fc4-bbc4-482a-cace-f5e2fc9318ba" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Example prompt\n", "prompt_template = \"\"\"\n", @@ -1577,7 +586,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1587,93 +596,13 @@ "outputId": "093c1167-d66d-42f7-e65d-ffe02b2d71ff" }, "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stdout", "output_type": "stream", "text": [ - "The report discusses the regulation of biometric identification, specifically the use of real-time systems in publicly accessible spaces for law enforcement purposes. The use of these systems is generally prohibited except in certain circumstances, such as searching for missing people or identifying perpetrators of serious criminal offences.\n", - "\n", - "The report outlines a number of exceptions and additional prohibitions related to biometric identification. For instance, biometric categorisation based on specific beliefs or characteristics is generally prohibited, along with untargeted scraping of facial images for creating facial recognition databases.\n", + "The report discusses the restrictions on the use of biometric identification by law enforcement in publicly accessible spaces. According to the document, real-time biometric identification is prohibited unless in exceptional cases where its use is strictly necessary and proportionate to achieving a substantial public interest. The use of post-remote biometric identification systems is also mentioned, noting the requirements for authorization and limitations on its use.\n", "\n", - "Additionally, the document mentions post-remote biometric identification, which is subject to additional safeguards. These include authorisation requirements and restrictions on their use for law enforcement purposes.\n", - "\n", - "The regulation also addresses the accuracy, robustness and cybersecurity of AI systems, including high-risk systems that involve biometric identification. Providers of such systems are responsible for ensuring compliance with these requirements.\n", - "\n", - "National competent authorities and market surveillance authorities are designated to oversee the implementation of these regulations. They have the power to enforce compliance, including the imposition of penalties for non-compliance.\n", - "\n", - "Overall, the report aims to establish a uniform legal framework for AI systems, especially those involving biometric identification, while ensuring the protection of fundamental rights and individual freedoms.\n" + "The report also highlights the classification of certain AI systems as high-risk, including biometric identification systems, emotion recognition systems, and biometric categorisation systems, with the exception of systems used for biometric verification. High-risk AI systems are subject to specific requirements and obligations.\n" ] } ], @@ -1690,8 +619,8 @@ "id": "zfpvo9WwbB6e" }, "source": [ - "\n", - "# Approach 3: Text rank" + "\n", + "## Approach 3: Text rank" ] }, { @@ -1705,7 +634,7 @@ "The solution presented in this document can be broken down into five functional steps:\n", "\n", "1. Break the document into chunks.\n", - " - This mirrors the first step in [Approach 2](#query-based-retrieval).\n", + " - This mirrors the first step in [Approach 2](#approach-2).\n", "\n", "2. Embed each chunk using an embedding model and construct a similarity matrix.\n", " - We utilize `co.embed` [documentation link](https://docs.cohere.com/reference/embed).\n", @@ -1714,10 +643,10 @@ " - We employ a package called [`NetworkX`](https://networkx.org/documentation/networkx-1.10/overview.html). It constructs a graph where the chunks are nodes, and the similarity score between them serves as the weight of the edges. Then, we calculate the centrality of each chunk as the sum of the edge weights adjacent to the node representing that chunk.\n", "\n", "4. Retain the highest-centrality chunks until the context limit is reached.\n", - " - This step follows a similar approach to [Approach 2](#query-based-retrieval).\n", + " - This step follows a similar approach to [Approach 2](#approach-2).\n", "\n", "5. Reassemble the shortened text by reordering chunks in their original order.\n", - " - This step mirrors the last step in [Approach 2](#query-based-retrieval).\n", + " - This step mirrors the last step in [Approach 2](#approach-2).\n", "\n", "See `text_rank` as the starting point.\n" ] @@ -1733,7 +662,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1742,80 +671,7 @@ "id": "4fWR-HKpmIHs", "outputId": "1ddc2bf4-90d1-44df-d4cd-6908546db506" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def text_rank(text: str, max_tokens: int, n_setences_per_passage: int) -> str:\n", " \"\"\"\n", @@ -1853,7 +709,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1862,80 +718,7 @@ "id": "YVVMr-S9mIHs", "outputId": "2fe871db-ac7a-4ac1-e7a1-e8c8292d95e4" }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Example summary prompt.\n", "prompt_template = \"\"\"\n", @@ -1951,7 +734,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1961,83 +744,11 @@ "outputId": "0a12951a-b917-4e69-a5c4-951907e32a90" }, "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stdout", "output_type": "stream", "text": [ - "The document outlines the European Union's Artificial Intelligence Act, which aims to regulate AI systems and models while promoting innovation. It establishes rules for developing, using, and monitoring AI, especially high-risk systems, to protect public interests and fundamental rights. The Act mandates risk management systems, data governance requirements, and transparency measures for high-risk AI. It also sets obligations for providers and deployers, including registration, and empowers competent authorities to enforce compliance. Additionally, it encourages codes of conduct and provides for AI regulatory sandboxes to support innovation. The EU will establish a database for high-risk AI systems, and the Commission will coordinate enforcement and promote best practices. Fines and penalties are proposed for non-compliance. The Act seeks to balance AI development and oversight, ensuring trustworthy and responsible use while fostering the EU's AI ecosystem.\n" + "The document outlines the requirements and obligations for developing and deploying AI systems in the European Union. It aims to establish a regulatory framework to foster innovation while ensuring the protection of fundamental rights and public interests. The regulation applies to providers and deployers of AI systems, including those established outside the EU. High-risk AI systems are subject to specific requirements, such as risk management, data governance, and transparency. Providers must ensure compliance and keep records, and deployers must use AI systems responsibly. The regulation also establishes an AI Office, advisory bodies, and a database for high-risk AI systems. Additionally, it addresses issues like testing, codes of conduct, and cooperation with third countries. Fines and penalties are proposed for non-compliance.\n" ] } ], @@ -2055,16 +766,12 @@ "source": [ "## Summary\n", "\n", - "In this notebook we present three useful methods to over come the limitations of context window size. In the following [blog post](TODO:add link), we talk more about how these methods can be evaluated." + "In this notebook we present three useful methods to over come the limitations of context window size. In the following [blog post](https://docs.cohere.com/page/chunking-strategies), we talk more about how these methods can be evaluated." ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "iUqiXtILroUY" - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, "source": [] } ], @@ -2086,9 +793,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/notebooks/guides/Meeting_Summaries_General_&_LangChain.ipynb b/notebooks/guides/Meeting_Summaries_General_&_LangChain.ipynb index 73117b24..2fd1876b 100644 --- a/notebooks/guides/Meeting_Summaries_General_&_LangChain.ipynb +++ b/notebooks/guides/Meeting_Summaries_General_&_LangChain.ipynb @@ -11,7 +11,15 @@ "Welcome to Cohere! In this notebook, you'll learn how to:\n", "* Use Cohere's Command-R model to summarize meeting transcripts.\n", "* Modify your prompt to include specific formatting instructions, especially if the model output is used in downstream applications.\n", - "* Use Command-R with LangChain for summarization." + "* Use Command-R with LangChain for summarization.\n", + "\n", + "### Table of contents:\n", + "1. [Setup](#setup)\n", + "2. [Load test data](#load)\n", + "3. [Simple summarization](#simple)\n", + "4. [More advanced formatting](#more)\n", + "5. [LangChain summarization](#langchain)\n", + "6. [Wrap up](#wrap)" ] }, { @@ -20,6 +28,8 @@ "id": "6SfEhd3O74--" }, "source": [ + "\n", + "\n", "## Setup\n", "\n", "You'll need a Cohere API key to run this notebook. If you don't have a key, head to https://cohere.com/ to generate your key." @@ -27,20 +37,19 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 7, "metadata": { "id": "H2TfKiPM3a6f" }, "outputs": [], "source": [ "%%capture\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" datasets tokenizers langchain" + "!pip install cohere datasets tokenizers langchain langchain-cohere" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -48,15 +57,7 @@ "id": "J1HzGqnY74bj", "outputId": "24fba7c5-a2ce-4c86-bc14-4ca2fb9137b5" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter your Cohere API key: ··········\n" - ] - } - ], + "outputs": [], "source": [ "import re\n", "from string import Template\n", @@ -74,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 9, "metadata": { "id": "SbVCPxMSD3fs" }, @@ -89,7 +90,7 @@ " if not s:\n", " print()\n", " else:\n", - " print(\"\\n\".join(line.strip() for line in re.findall(rf\".{{1,{maxchars}}}(?:\\s+|$)\", s)))\n" + " print(\"\\n\".join(line.strip() for line in re.findall(rf\".{{1,{maxchars}}}(?:\\s+|$)\", s)))" ] }, { @@ -98,6 +99,8 @@ "id": "ABgVdI7I8Jmk" }, "source": [ + "\n", + "\n", "## Load test data\n", "\n", "Let's load a meeting transcript to see Command in action!\n", @@ -109,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -198,116 +201,6 @@ "outputId": "30c66020-c5b0-4984-fce6-9ae018b7abf0" }, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", - "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", - "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", - "You will be able to reuse this secret in all of your notebooks.\n", - "Please note that authentication is recommended but still optional to access public models or datasets.\n", - " warnings.warn(\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "43225bc344ed4374931511b8630baae4", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Downloading readme: 0%| | 0.00/21.0 [00:00\n", + "\n", "## Simple summarization\n", "\n", "First, we'll show an example of a simple summarization task. The prompt template we are using is shown below, and we can obtain the completion using a one line call to the Cohere API." @@ -438,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -452,9 +309,9 @@ "output_type": "stream", "text": [ "The team discusses the time-consuming process of identifying instances of speaker overlap in audio\n", - "recordings. PhD C suggests using close-talking microphones and automated methods to establish ground\n", - "truth data, which Grad G is working on. This data would help develop a more efficient system than\n", - "manual marking.\n" + "data. PhD C suggests using close-talking microphones and automated methods to establish ground truth\n", + "data, which Grad G is working on. This data would help develop a more efficient system than manual\n", + "marking.\n" ] } ], @@ -484,7 +341,7 @@ "1. We include a preamble imbuing the model with a persona.\n", "2. We use Markdown-style headers (i.e. with `##`) to delineate the preamble, the text-to-summarise, the instructions, and the output\n", "\n", - "For some other prompting best practices and tips/tricks, see our [prompting guide](https://docs.google.com/document/d/1k0KBiOUEPq65vqEuAQyg6Y5l1s2_Ybwv-lOLho6NHsw/edit)!" + "For some other prompting best practices and tips/tricks, see our [prompting guide](https://docs.cohere.com/docs/crafting-effective-prompts)!" ] }, { @@ -493,6 +350,8 @@ "id": "YT6nsN6DK_xt" }, "source": [ + "\n", + "\n", "## More advanced formatting\n", "\n", "That worked well, but what if you want to have more control over the summary? What if you wanted a bulleted summary and wanted exactly 3 bullets in a json structure?\n", @@ -502,7 +361,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -518,9 +377,9 @@ "```json\n", "{\n", " \"summary_bullets\": [\n", - " \"There's a need to identify instances of speaker overlap in recorded meetings, but it's a time-consuming task to mark these events manually.\",\n", - " \"An alternative is to infer speaker overlap using various measurements of energy in the audio, such as close-talking microphones, LPC residuals, etc.\",\n", - " \"A threshold-based program that detects speech based on volume can speed up the process, and further improvements can be explored once a robust system is in place.\"\n", + " \"There are many ways to study and mark speech overlap in a busy environment, but it's a time-consuming task.\",\n", + " \"A threshold-based program that uses close-talking mics to infer speech overlap could speed up the process. The program looks for runs after applying a median filter and appears to work.\",\n", + " \"Having a ground truth to compare the automated results against is important, and a human review of the data is still necessary.\"\n", " ]\n", "}\n", "```\n" @@ -563,7 +422,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -576,8 +435,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "The team discusses using various methods, including close-talking mics and threshold-based volume\n", - "filters, to accurately identify instances of speaker overlap in recorded meetings.\n" + "The team discusses using various methods, including close-talking microphones and automated volume\n", + "thresholding, to accurately identify instances of speaker overlap in recorded meetings as part of a\n", + "research project.\n" ] } ], @@ -602,13 +462,15 @@ "id": "KOaKiT6Ztkbz" }, "source": [ + "\n", + "\n", "## LangChain summarization\n", "It's also very easy to use Command-R with LangChain for summarization." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -621,7 +483,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.10/dist-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The function `run` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n", + "/Users/boyu/miniconda3/envs/test/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 0.3.0. Use RunnableSequence, e.g., `prompt | llm` instead.\n", + " warn_deprecated(\n", + "/Users/boyu/miniconda3/envs/test/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 0.3.0. Use invoke instead.\n", " warn_deprecated(\n" ] }, @@ -635,18 +499,19 @@ "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "The team discusses the time-consuming process of identifying instances of speaker overlap in audio\n", - "recordings. PhD C suggests using close-talking microphones and automated methods to establish ground\n", - "truth data, which Grad G is working on. This data would help develop a more efficient system than\n", - "manual marking.\n" + "data. PhD C suggests using close-talking microphones and automated methods to establish ground truth\n", + "data, which Grad G is working on. This data would help develop a more efficient system than manual\n", + "marking.\n" ] } ], "source": [ "from langchain.chains.combine_documents.stuff import StuffDocumentsChain\n", "from langchain.chains.llm import LLMChain\n", - "from langchain.prompts import PromptTemplate\n", + "from langchain_cohere import ChatCohere\n", "from langchain.docstore.document import Document\n", - "from langchain_community.chat_models import ChatCohere\n", + "from langchain.prompts import PromptTemplate\n", + "\n", "\n", "llm = ChatCohere(\n", " cohere_api_key=co_api_key,\n", @@ -691,13 +556,15 @@ "id": "uj8kdy5auKKY" }, "source": [ + "\n", + "\n", "## Wrap up\n", "\n", "Those were some simple examples of how you can use Cohere's Command-R model for summarization.\n", "\n", - "For more advanced summarization objectives and to see some other cool things you can do with the Command-R model, see [recipes for better meeting notes summaries](https://colab.research.google.com/drive/1XqRpJH7qRnRTbOEt6kthwqZG6gtEn4gN#scrollTo=LplM9PSe8djM).\n", + "For more advanced summarization objectives and to see some other cool things you can do with the Command-R model, see [recipes for better meeting notes summaries](https://github.com/cohere-ai/notebooks/blob/main/notebooks/guides/Recipes_for_better_meeting_notes_summary.ipynb).\n", "\n", - "In cases where you can't fit the input text into the context window, see our [cookbook for long document strategies](https://colab.research.google.com/drive/1zxSAbruOWwWJHNsj3N56uxZtUeiS7Evd#scrollTo=4JgYYTg7Shvq).\n", + "In cases where you can't fit the input text into the context window, see our [cookbook for long document strategies](https://github.com/cohere-ai/notebooks/blob/main/notebooks/guides/Long_form_General_Strategies.ipynb).\n", "\n", "For more information, you can reach out to us at summarize@cohere.com!" ] @@ -721,7 +588,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.11" + "version": "3.11.5" }, "widgets": { "application/vnd.jupyter.widget-state+json": { diff --git a/notebooks/guides/Migrating_Monolithic_Prompts_to_Command_R_with_RAG.ipynb b/notebooks/guides/Migrating_Monolithic_Prompts_to_Command_R_with_RAG.ipynb index 6f60eb74..8b288d09 100644 --- a/notebooks/guides/Migrating_Monolithic_Prompts_to_Command_R_with_RAG.ipynb +++ b/notebooks/guides/Migrating_Monolithic_Prompts_to_Command_R_with_RAG.ipynb @@ -97,7 +97,7 @@ "id": "JfS7y2zD-ehv" }, "source": [ - "This application scenario is a common LLM-as-assistant use case. Given some context, help the user to complete a task. In this case, the task is to write a concise autobiographical summary." + "This application scenario is a common LLM-as-assistant use case: given some context, help the user to complete a task. In this case, the task is to write a concise autobiographical summary." ] }, { @@ -535,7 +535,7 @@ "id": "cEdYRffp06d2" }, "source": [ - "On March 21st, the DOJ announced that it is [suing apple](https://www.theverge.com/2024/3/21/24107659/apple-doj-lawsuit-antitrust-documents-suing) for anti-competitive practices. The [complaint](https://www.justice.gov/opa/media/1344546/dl) is 88 pages long and consists of about 230 paragraphs of text. To understand what the suit alleges, a common use case would be to ask for a summary. Because Command-R has a context window of 128K, even an 88-page legal complaint fits comfortably within the window." + "On March 21st, the DOJ announced that it is [suing Apple](https://www.theverge.com/2024/3/21/24107659/apple-doj-lawsuit-antitrust-documents-suing) for anti-competitive practices. The [complaint](https://www.justice.gov/opa/media/1344546/dl) is 88 pages long and consists of about 230 paragraphs of text. To understand what the suit alleges, a common use case would be to ask for a summary. Because Command-R has a context window of 128K, even an 88-page legal complaint fits comfortably within the window." ] }, { @@ -658,7 +658,7 @@ "id": "7a81dU5U3LIY" }, "source": [ - "The summary seems clear enough. But I am interested in the specific allegations that the DOJ makes. For example, skimming the full complaint, it looks like the DOJ is alleging that Apple could encrypt text messages sent to Android phones if it wanted to do so. We can ammend the rendered prompt and ask:" + "The summary seems clear enough. But we are interested in the specific allegations that the DOJ makes. For example, skimming the full complaint, it looks like the DOJ is alleging that Apple could encrypt text messages sent to Android phones if it wanted to do so. We can amend the rendered prompt and ask:" ] }, { @@ -955,15 +955,6 @@ "\n", "In this cookbook we have shown how one can easily take an existing monolithic prompt and migrate it to the RAG paradigm to get less hallucination, grounded information, and in-line citations. We also demonstrated Command-R's ability to re-write an instruction prompt in a single shot to make it more concise and potentially lead to higher quality completions." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "0vTsJc-ZHleg" - }, - "outputs": [], - "source": [] } ], "metadata": { @@ -985,7 +976,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/guides/Multilingual_Search_with_Cohere_and_Langchain.ipynb b/notebooks/guides/Multilingual_Search_with_Cohere_and_Langchain.ipynb index 83eedfc6..253c5a3b 100644 --- a/notebooks/guides/Multilingual_Search_with_Cohere_and_Langchain.ipynb +++ b/notebooks/guides/Multilingual_Search_with_Cohere_and_Langchain.ipynb @@ -1,3687 +1,3658 @@ { - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "5WNncDXelfhy" - }, - "source": [ - "# Multilingual Search with Cohere and Langchain" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "5WNncDXelfhy" + }, + "source": [ + "# Multilingual Search with Cohere and Langchain" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PGbjnPUwH8tp" + }, + "source": [ + "***Read the accompanying [blog post here](https://txt.cohere.ai/search-cohere-langchain/).***" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mjR6RAkgf6EM" + }, + "source": [ + "This notebook contains two examples for performing multilingual search using Cohere and Langchain. Langchain is a library that assists the development of applications built on top of large language models (LLMs), such as Cohere's models.\n", + "\n", + "In short, Cohere makes it easy for developers to leverage LLMs and Langchain makes it easy to build applications with these models.\n", + "\n", + "We'll go through the following examples:\n", + "- **Example 1 - Basic Multilingual Search**\n", + "\n", + " This is a simple example of multilingual search over a list of documents.\n", + "\n", + " The steps in summary:\n", + " - Import a list of documents\n", + " - Embed the documents and store them in an index\n", + " - Enter a query\n", + " - Return the document most similar to the query\n", + "- **Example 2 - Search-Based Question Answering**\n", + "\n", + " This example shows a more involved example where search is combined with text generation to answer questions about long-form documents.\n", + "\n", + " The steps in summary:\n", + " - Add an article and chunk it into smaller passages\n", + " - Embed the passages and store them in an index\n", + " - Enter a question\n", + " - Answer the question based on the most relevant documents" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "LDkRgKDwEWWy", + "outputId": "6afa8b14-f88f-4984-f9cb-15a332a4eebf" + }, + "outputs": [ { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "PGbjnPUwH8tp" - }, - "source": [ - "***Read the accompanying [blog post here](https://txt.cohere.ai/search-cohere-langchain/).***" + "data": { + "text/plain": [ + "True" ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from langchain.embeddings.cohere import CohereEmbeddings\n", + "from langchain.llms import Cohere\n", + "from langchain.prompts import PromptTemplate\n", + "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", + "from langchain.chains.question_answering import load_qa_chain\n", + "from langchain.chains import RetrievalQA\n", + "from langchain.vectorstores import Qdrant\n", + "from langchain.document_loaders import TextLoader\n", + "import textwrap as tr\n", + "import random\n", + "import dotenv\n", + "import os\n", + "\n", + "dotenv.load_dotenv(\".env\") # Upload an '.env' file containing an environment variable named 'COHERE_API_KEY' using your Cohere API Key" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oHUJHp6dZxG2" + }, + "source": [ + "# Example 1 - Basic Multilingual Search" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U111MGZvhM7O" + }, + "source": [ + "![Example-1---Basic-Multilingual-Search.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXgAAAMUCAYAAAAG7U8sAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAFaOSURBVHgB7N0/jBRp3if4h3cb8w6k29a91gtGI60FbdC7zokyKGk8MLrdBmlpb1WMBLMmaAXmqpAa3CmjwWVGos1XcBLonL1hJMA7NUax1kpzp4E7a1W7x/U35h4mOjv/V9afJ+rzkVKVVRUZGRmRmfGLbzzxPMd2dnY+FgAAAAAAmvMPBQAAAACAJgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGjUZwU4sp48eVLevHnT3b9y5Uo5depUOcz6y7uMW7duFVbvxYsX5fXr1+XVq1flw4cP5f3799176csvvywXLlwo586dKwDAwch+OfVT6qh37951v588ebLbP6+trXX76pak5vjxxx/nmra+ztZe41Ey7/ZMbXn69GnbEmCCYzs7Ox8LcCR999135YcffujuP336tCvyD7P+8i7j5++7wmrk4PDBgwfl/v373f1pUpDfvn27O4kAAOyf7Kvv3LkzdV/d2n764cOH5dq1aws9Jq/x6tWrTvYfQotuz4T2ly5d6ransBfg73TRALBCac165syZ7nbz5s0yRGkF9NVXX808YKzSWiiF+/nz57v7AMDey773xo0bv9hXJxxLK8i+up8eat0SeY2pW7744ot9q0XyPLUmXDSQZrK8nxMKX7x4sVuvakuWkZNf9fM57xUBcNjpogGOsO3t7dKqtDI5rC1N6nqdJ/xsTcLdFNT915aW35cvX+5aUeTAMbIOMm1a+Nb1kUvw8thnz54d+u5AAKBld+/e7UKwamNjo2vx2O826fnz5900dbrssxP+ZtpW5PVsbm6O/V/tmiKvr9YiCQO//vrr8vLly7If6vOqe+aTmnJcK+tst3QDlvdsbrUOzbbN72pLFpX30JCP2TiaBLxwRKVQavmMdw5ADnuXEkOT90s/3E0hvbW1NXY75H/5ew4Sc8CYA808rs4jB1Y1DAYAVqe2Vq0SgF6/fv1X02U/nVv22dlPRx737bffNrOPznJOqwdzAjqBYV5XfY054Zz7ums4fGr9OEnqyry/02Vb3Z61thTyAkedLhrgCMiZ7fX19V/ccrl8yy142X953/TD3RTS84TsOahMH8/1YDGF+JAvAwWAg5QTq1Wu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nufPny9/+ctfCsOhNgYA9ot6cj7/UJjqxYsX5cSJEwpYAIAFpX46d+5cef78eWEY1MYAwH5ST85HwDtD3kBra2sFAIDFpSB/8+ZNYRjUxgDAflNPzibgneH169eKWACAJV24cEGLiwFRGwMA+009OZuAd4bt7W2XoAEALOnLL78sr169KgyD2hgA2G/qydkEvDOkM2dFLADActJf64cPHwrDoDYGAPabenK2Yzs7Ox8LEx0/frz8vI4KAADLUU8Nh20JABwENch0WvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAoz4rAMCh9e7du0/3T506VQAAAKBPC14Opbt375bjx49PvH3++efl/Pnz5dq1a+XHH38sAEPy4sWLsr6+3n3XffHFF59u+f7Ld9/Dhw9/EfwCAIdL9uOzjmcyzc2bN7v9PgDshoCXJr1//768fv26Czm+/vrrLvjIfYYv2z7Bfm7Pnz8vMCQJbXOwd/Hixe79nff7qHz35f2faXzvAUCbso/Pvv7+/fvdPj37fydvj4Zs93o8M67WA1iGLho49DY3N8vJkyd/8bcUPwk5ctve3u5+zw4yP2/dulUYrg8fPnwKtdbW1goMxZs3b7oDvFro53vvypUr5cKFC5++AzPNkydPugMD33sAcPhlH57jmVH1eCb79ci+PY1Wtra2uv0/w5VtX49nbt++/atjXYBlCHg59C5fvjy138nsHNOlQ4LeO3fudH8TdgAtSaHfD3c3NjbGFvw5qZH/jX7vZbr8HQA4XE6cODE1sE0N8MMPP3T79cjJ2zwmx0AA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AKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFF32zsAAAAAAOR8WXumO1I3wwEAAAAASUVORK5CYII=)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PVTkZXLsHiVs" + }, + "source": [ + "### Import a list of documents" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187, + "referenced_widgets": [ + "7c8e1e4eee714bc086c3f84eee5941fc", + "4334b4f6fc7048eab0d146b6ffc437d1", + "c8e13e321a9a4e0b88c717a1a8065619", + "c1f14f69e97f44598d9c4f8d789131fb", + "25a079a3d58644f4a5306ee2cb42dbde", + "be8b3f4e73fc44f390e9a147df786e53", + "3bda8233967642229fe778b4a8402f52", + "c37f294926f945898096874d324ee2ae", + "941ab80a14aa4a1bb3943dd77aca85d7", + "1f1331ab4e734cdaa66cf28d7278f980", + "d773c0f65a014ae08f533bf2348c1831", + "4cf6a31b3be945cbb82f8239e7e2642e", + "7fd82914b89343538aa08b36f4752f4b", + "35132c00838046bca253f31350a3190b", + "190a428569a74beb8b90aa278c629bd2", + "01545efb5b78418791ce0f8c763873ce", + "d426d4b5b86c4582a17bf21fe5f021d4", + "2d69c8378b194aa3a8634848da5ee79a", + "88ff8d07f6ce430db2772b8bf24294e8", + "f5e168c246714295a10a64fbb1ef2ee3", + "6d1ea14b22034d2d9ab16aa5a24566dc", + "6c0193f68df143e0a7907c6a577b07a6", + "7fa8f3f5c00c493bb7283bc90c33df5e", + "59f2ed0257d6422d84fa23898e5d9a10", + "9236baef198c44ae8607c7888e899bc8", + "3647d22aaf934b53bf925dc22e2ce69a", + "687cfefc80a54edd84eb22baf805c905", + "533f3a17f8d1442490a2d6167d89550b", + "ce82f835dd2b45a181a53407505b0cfc", + "02e46682b2434a0c872f35db3d7b367e", + "3da4f3751cb54cf2938aea924ab33aa0", + "89f757fbb1ef4fa8b557c04926871096", + "94ebb17c331649fc812a66231532ee03", + "df522159441841cda1f97d63aab5ad9e", + "a9f4707824454e35b2273412c4586b8d", + "d849ae343e51419c803c29c24a16dd01", + "65b7f23304a243878c43ea391885ee85", + "85f4ab947d774115baf64332f64248bd", + "efa03832003244a490cfcb34edf7ccbe", + "9e46610e715444cbbc2f978a0acd0ed0", + "3948a575b3ee4a199f1055e93d8270ee", + "2ee59cbc091346168c3b4511f64b018a", + "c5296022707240b393be4146e983083c", + "8653f9b6a25446cc8d7d34ffd4e48ca8", + "a61d6191c53e4dd2a1cbdb9826f5ae70", + "e868b829ec7a4795955034ebb8b109a6", + "1385286d855a46c8b19704a95e5992b4", + "b7bbc695e0f248a0ac1e79a1d546df8e", + "034072a591b94d3daf4284aadcff935f", + "d24e60c7e4664e0ba11cce85c647e526", + "23bbe3c6dfcb42c7a0a1c826bc35076d", + "5cf957caabe043139dc587e8651a28b1", + "bfb987eb24644819ba52b2fc7bc865de", + "8e7d772e693c427c9bcfc7535a524979", + "d646a9a4cc5a4876a7fa185bf9eb3ccf", + "09c17a96b5534b78b1d9bfc2f7bc83d5", + "735bfe1c1ff6402d826257313d68b21b", + "df1b4d3501ed457b86b60a5449d1e1da", + "771c7097b5be45ffac31e70117376903", + "996f65fcf7a04703868717652927e5e2", + "5edafe62c55449709c304c11dc847e82", + "5ed53479e65749a68e2ae1f70fff1db0", + "b04f406f1a2a46818d034a80d13f6664", + "fcc06cd646ff425b9172312808dd3e24", + "d9dd5b64f0ee40359a4c577f4358248f", + "baf658cc369745b7bad7f18302e385d9", + "b07ffeedc45a4fe9919f99d71a2ea3f2", + "211f7336a3b9455f8cd67bd0ee4113ae", + "2bd5fe14d3d44d85be32c5c78f5b7568", + "6850b87ff2fa49eb9fbfb3c3492efbb3", + "6def2ecb657845a3bae18bad85950991", + "68bf09957e83431b8d299f1ab15d5f7e", + "28adfb59f3e24851ba617e0087e5293f", + "10ca522adeca4ba4bb2d4f9373a363f4", + "5f9f737d68234b9a9cd069105ab20ea2", + "d298dc9202dc49aba09b66969b3d19f9", + "6e09dadf883440038a7a47f0d9723ae6", + "cd23755e6122427e9d95eb808b7900c2", + "62eb05321e2d4265b033544921f92053", + "3627640fb7d14ac09c9fdcbfb2159152", + "c05f2a082d5e4a0c8f3b9b6952eff208", + "bf6033cd5d0c4ef5ac934ed6e8adaeb6", + "463628ae5afc4c8f9a51f2c4ed038d12", + "1ac7e3656e43480c8af4038d2e7d5432", + "6e600a0c3f36439899b40cdc53ed7c8c", + "672ec8abe8b34b8dab6d4af20f0302c7", + "57cf77bba44141359639c0268ced8934", + "6a7d1421176f4b62af003a4b2f18815b" + ] }, + "id": "WN-sQquOb4VQ", + "outputId": "f547e445-3b89-4b87-f9a3-7f7fa08053f4" + }, + "outputs": [ { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "mjR6RAkgf6EM" - }, - "source": [ - "This notebook contains two examples for performing multilingual search using Cohere and Langchain. Langchain is a library that assists the development of applications built on top of large language models (LLMs), such as Cohere's models.\n", - "\n", - "In short, Cohere makes it easy for developers to leverage LLMs and Langchain makes it easy to build applications with these models.\n", - "\n", - "We'll go through the following examples:\n", - "- **Example 1 - Basic Multilingual Search**\n", - "\n", - " This is a simple example of multilingual search over a list of documents.\n", - "\n", - " The steps in summary:\n", - " - Import a list of documents\n", - " - Embed the documents and store them in an index\n", - " - Enter a query\n", - " - Return the document most similar to the query\n", - "- **Example 2 - Search-Based Question Answering**\n", - "\n", - " This example shows a more involved example where search is combined with text generation to answer questions about long-form documents.\n", - "\n", - " The steps in summary:\n", - " - Add an article and chunk it into smaller passages\n", - " - Embed the passages and store them in an index\n", - " - Enter a question\n", - " - Answer the question based on the most relevant documents" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading and preparing dataset 350.79 KiB (download: 350.79 KiB, generated: 636.90 KiB, total: 987.69 KiB) to /root/tensorflow_datasets/trec/1.0.0...\n" + ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "sDhfWxSaEOpS" + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7c8e1e4eee714bc086c3f84eee5941fc", + "version_major": 2, + "version_minor": 0 }, - "outputs": [], - "source": [ - "# TODO: upgrade to \"cohere>5\"", -"! pip install \"cohere<5\" langchain qdrant-client tfds-nightly python-dotenv > /dev/null" + "text/plain": [ + "Dl Completed...: 0 url [00:00, ? url/s]" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "LDkRgKDwEWWy", - "outputId": "6afa8b14-f88f-4984-f9cb-15a332a4eebf" + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4cf6a31b3be945cbb82f8239e7e2642e", + "version_major": 2, + "version_minor": 0 }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from langchain.embeddings.cohere import CohereEmbeddings\n", - "from langchain.llms import Cohere\n", - "from langchain.prompts import PromptTemplate\n", - "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", - "from langchain.chains.question_answering import load_qa_chain\n", - "from langchain.chains import RetrievalQA\n", - "from langchain.vectorstores import Qdrant\n", - "from langchain.document_loaders import TextLoader\n", - "import textwrap as tr\n", - "import random\n", - "import dotenv\n", - "import os\n", - "\n", - "dotenv.load_dotenv(\".env\") # Upload an '.env' file containing an environment variable named 'COHERE_API_KEY' using your Cohere API Key" + "text/plain": [ + "Dl Size...: 0 MiB [00:00, ? MiB/s]" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "oHUJHp6dZxG2" + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7fa8f3f5c00c493bb7283bc90c33df5e", + "version_major": 2, + "version_minor": 0 }, - "source": [ - "# Example 1 - Basic Multilingual Search" + "text/plain": [ + "Extraction completed...: 0 file [00:00, ? file/s]" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "U111MGZvhM7O" + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "df522159441841cda1f97d63aab5ad9e", + "version_major": 2, + "version_minor": 0 }, - "source": [ - "![Example-1---Basic-Multilingual-Search.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXgAAAMUCAYAAAAG7U8sAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAFaOSURBVHgB7N0/jBRp3if4h3cb8w6k29a91gtGI60FbdC7zokyKGk8MLrdBmlpb1WMBLMmaAXmqpAa3CmjwWVGos1XcBLonL1hJMA7NUax1kpzp4E7a1W7x/U35h4mOjv/V9afJ+rzkVKVVRUZGRmRmfGLbzzxPMd2dnY+FgAAAAAAmvMPBQAAAACAJgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGiUgBcAAAAAoFECXgAAAACARgl4AQAAAAAaJeAFAAAAAGjUZwU4sp48eVLevHnT3b9y5Uo5depUOcz6y7uMW7duFVbvxYsX5fXr1+XVq1flw4cP5f3799176csvvywXLlwo586dKwDAwch+OfVT6qh37951v588ebLbP6+trXX76pak5vjxxx/nmra+ztZe41Ey7/ZMbXn69GnbEmCCYzs7Ox8LcCR999135YcffujuP336tCvyD7P+8i7j5++7wmrk4PDBgwfl/v373f1pUpDfvn27O4kAAOyf7Kvv3LkzdV/d2n764cOH5dq1aws9Jq/x6tWrTvYfQotuz4T2ly5d6ransBfg73TRALBCac165syZ7nbz5s0yRGkF9NVXX808YKzSWiiF+/nz57v7AMDey773xo0bv9hXJxxLK8i+up8eat0SeY2pW7744ot9q0XyPLUmXDSQZrK8nxMKX7x4sVuvakuWkZNf9fM57xUBcNjpogGOsO3t7dKqtDI5rC1N6nqdJ/xsTcLdFNT915aW35cvX+5aUeTAMbIOMm1a+Nb1kUvw8thnz54d+u5AAKBld+/e7UKwamNjo2vx2O826fnz5900dbrssxP+ZtpW5PVsbm6O/V/tmiKvr9YiCQO//vrr8vLly7If6vOqe+aTmnJcK+tst3QDlvdsbrUOzbbN72pLFpX30JCP2TiaBLxwRKVQavmMdw5ADnuXEkOT90s/3E0hvbW1NXY75H/5ew4Sc8CYA808rs4jB1Y1DAYAVqe2Vq0SgF6/fv1X02U/nVv22dlPRx737bffNrOPznJOqwdzAjqBYV5XfY054Zz7ums4fGr9OEnqyry/02Vb3Z61thTyAkedLhrgCMiZ7fX19V/ccrl8yy142X953/TD3RTS84TsOahMH8/1YDGF+JAvAwWAg5QTq1Wu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nufPny9/+ctfCsOhNgYA9ot6cj7/UJjqxYsX5cSJEwpYAIAFpX46d+5cef78eWEY1MYAwH5ST85HwDtD3kBra2sFAIDFpSB/8+ZNYRjUxgDAflNPzibgneH169eKWACAJV24cEGLiwFRGwMA+009OZuAd4bt7W2XoAEALOnLL78sr169KgyD2hgA2G/qydkEvDOkM2dFLADActJf64cPHwrDoDYGAPabenK2Yzs7Ox8LEx0/frz8vI4KAADLUU8Nh20JABwENch0WvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAowS8AAAAAACNEvACAAAAADRKwAsAAAAA0CgBLwAAAABAoz4rAMCh9e7du0/3T506VQAAAKBPC14Opbt375bjx49PvH3++efl/Pnz5dq1a+XHH38sAEPy4sWLsr6+3n3XffHFF59u+f7Ld9/Dhw9/EfwCAIdL9uOzjmcyzc2bN7v9PgDshoCXJr1//768fv26Czm+/vrrLvjIfYYv2z7Bfm7Pnz8vMCQJbXOwd/Hixe79nff7qHz35f2faXzvAUCbso/Pvv7+/fvdPj37fydvj4Zs93o8M67WA1iGLho49DY3N8vJkyd/8bcUPwk5ctve3u5+zw4yP2/dulUYrg8fPnwKtdbW1goMxZs3b7oDvFro53vvypUr5cKFC5++AzPNkydPugMD33sAcPhlH57jmVH1eCb79ci+PY1Wtra2uv0/w5VtX49nbt++/atjXYBlCHg59C5fvjy138nsHNOlQ4LeO3fudH8TdgAtSaHfD3c3NjbGFvw5qZH/jX7vZbr8HQA4XE6cODE1sE0N8MMPP3T79cjJ2zwmx0AA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AKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFGCFwAAAAAgSvACAAAAAEQJXgAAAACAKMELAAAAABAleAEAAAAAogQvAAAAAECU4AUAAAAAiBK8AAAAAABRghcAAAAAIErwAgAAAABECV4AAAAAgCjBCwAAAAAQJXgBAAAAAKIELwAAAABAlOAFAAAAAIgSvAAAAAAAUYIXAAAAACBK8AIAAAAARAleAAAAAIAowQsAAAAAECV4AQAAAACiBC8AAAAAQJTgBQAAAACIErwAAAAAAFF32zsAAAAAAOR8WXumO1I3wwEAAAAASUVORK5CYII=)" + "text/plain": [ + "Generating splits...: 0%| | 0/2 [00:00] 11.71K --.-KB/s in 0s \n", + "\n", + "2023-06-08 06:11:20 (115 MB/s) - ‘steve-jobs-commencement.txt’ saved [11993/11993]\n", + "\n" + ] + } + ], + "source": [ + "# We'll use Steve Jobs' Stanford University commencement address as the example. Link: https://news.stanford.edu/2005/06/12/youve-got-find-love-jobs-says/\n", + "\n", + "!wget 'https://docs.google.com/uc?export=download&id=1f1INWOfJrHTFmbyF_0be5b4u_moz3a4F' -O steve-jobs-commencement.txt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "obv6NbUcNfB_" + }, + "outputs": [], + "source": [ + "loader = TextLoader(\"steve-jobs-commencement.txt\")\n", + "documents = loader.load()\n", + "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)\n", + "texts = text_splitter.split_documents(documents)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DHvoF9CB9apc" + }, + "source": [ + "## Embed the passages and store them in an index" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "11Bx0k2LGIH-" + }, + "outputs": [], + "source": [ + "embeddings = CohereEmbeddings(model = \"multilingual-22-12\")\n", + "db = Qdrant.from_documents(texts, embeddings, location=\":memory:\", collection_name=\"my_documents\", distance_func=\"Dot\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xQsrDUQo9poh" + }, + "source": [ + "## Enter a question" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SW90c8kOqdow" + }, + "outputs": [], + "source": [ + "questions = [\n", + " \"What did the author liken The Whole Earth Catalog to?\",\n", + " \"What was Reed College great at?\",\n", + " \"What was the author diagnosed with?\",\n", + " \"What is the key lesson from this article?\",\n", + " \"What did the article say about Michael Jackson?\",\n", + " ]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HXhkK22JvNa1" + }, + "source": [ + "## Answer the question based on the most relevant documents\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "-dgBvF5HI9Wd" + }, + "outputs": [], + "source": [ + "# Create our own prompt template\n", + "\n", + "prompt_template = \"\"\"Text: {context}\n", + "\n", + "Question: {question}\n", + "\n", + "Answer the question based on the text provided. If the text doesn't contain the answer, reply that the answer is not available.\"\"\"\n", + "\n", + "PROMPT = PromptTemplate(\n", + " template=prompt_template, input_variables=[\"context\", \"question\"]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "8wa_YjzpcEAE", + "outputId": "31120ad3-034a-42f1-96a3-7454cd68ade5" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "d6qxf0N0H_Cl" - }, - "outputs": [], - "source": [ - "# Return document most similar to the query\n", - "answers = []\n", - "for query in queries:\n", - " docs = db.similarity_search(query)\n", - " answers.append(docs[0].page_content)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", + "\n", + "Question: What did the author liken The Whole Earth Catalog to?\n", + "Answer: It was sort of like Google in paperback form, 35 years before Google came along\n", + "\n", + "Sources:\n", + "1: When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a\n", + "fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960s, before\n", + "personal computers and desktop publishing, so it was all made with typewriters, scissors and Polaroid cameras. It was sort of like Google in paperback\n", + "form, 35 years before Google came along: It was\n", + "2: Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the\n", + "mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find\n", + "yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they\n", + "signed off. Stay Hungry. Stay Foolish. And I have always\n", + "3: idealistic, and overflowing with neat tools and great notions.\n", + "4: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", + "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", + "\n", + "Question: What was Reed College great at?\n", + "Answer: Reed College was great at calligraphy instruction.\n", + "\n", + "Sources:\n", + "1: Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every\n", + "drawer, was beautifully hand calligraphed. Because I had dropped out and didn’t have to take the normal classes, I decided to take a calligraphy class\n", + "to learn how to do this. I learned about serif and sans serif typefaces, about varying the amount of space between different letter combinations,\n", + "about what makes great typography great. It was\n", + "2: I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why\n", + "did I drop out?\n", + "3: never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they\n", + "do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backward 10 years\n", + "later.\n", + "4: OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the\n", + "required classes that didn’t interest me, and begin dropping in on the ones that looked interesting.\n", + "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", + "\n", + "Question: What was the author diagnosed with?\n", + "Answer: The author was diagnosed with cancer.\n", + "\n", + "Sources:\n", + "1: I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my\n", + "intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed\n", + "the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with\n", + "surgery. I had the surgery and I’m fine now.\n", + "2: About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn’t even know\n", + "what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than\n", + "three to six months. My doctor advised me to go home and get my affairs in order, which is doctor’s code for prepare to die. It means to try to tell\n", + "your kids everything you thought you’d have the\n", + "3: Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the\n", + "mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find\n", + "yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they\n", + "signed off. Stay Hungry. Stay Foolish. And I have always\n", + "4: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", + "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", + "\n", + "Question: What is the key lesson from this article?\n", + "Answer: The key lesson from this article is that you have to trust that the dots will somehow connect in your future. You have to trust in something -- your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.\n", + "\n", + "Sources:\n", + "1: Again, you can’t connect the dots looking forward; you can only connect them looking backward. So you have to trust that the dots will somehow connect\n", + "in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all\n", + "the difference in my life. My second story is about love and loss.\n", + "2: Remembering that I’ll be dead soon is the most important tool I’ve ever encountered to help me make the big choices in life. Because almost everything\n", + "— all external expectations, all pride, all fear of embarrassment or failure — these things just fall away in the face of death, leaving only what is\n", + "truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are\n", + "already naked. There is no reason not to follow your\n", + "3: Your time is limited, so don’t waste it living someone else’s life. Don’t be trapped by dogma — which is living with the results of other people’s\n", + "thinking. Don’t let the noise of others’ opinions drown out your own inner voice. And most important, have the courage to follow your heart and\n", + "intuition. They somehow already know what you truly want to become. Everything else is secondary.\n", + "4: I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down — that I had dropped the baton\n", + "as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and\n", + "I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple\n", + "had not changed that one bit. I had been rejected,\n", + "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", + "\n", + "Question: What did the article say about Michael Jackson?\n", + "Answer: The text did not provide information about Michael Jackson.\n", + "\n", + "Sources:\n", + "1: baby boy; do you want him?” They said: “Of course.” My biological mother later found out that my mother had never graduated from college and that my\n", + "father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents\n", + "promised that I would someday go to college.\n", + "2: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", + "3: I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down — that I had dropped the baton\n", + "as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and\n", + "I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple\n", + "had not changed that one bit. I had been rejected,\n", + "4: This was the closest I’ve been to facing death, and I hope it’s the closest I get for a few more decades. Having lived through it, I can now say this\n", + "to you with a bit more certainty than when death was a useful but purely intellectual concept:\n" + ] + } + ], + "source": [ + "chain_type_kwargs = {\"prompt\": PROMPT}\n", + "\n", + "qa = RetrievalQA.from_chain_type(llm=Cohere(model=\"command\", temperature=0), \n", + " chain_type=\"stuff\", \n", + " retriever=db.as_retriever(), \n", + " chain_type_kwargs=chain_type_kwargs, \n", + " return_source_documents=True)\n", + "\n", + "for question in questions:\n", + " answer = qa({\"query\": question})\n", + " result = answer[\"result\"].replace(\"\\n\",\"\").replace(\"Answer:\",\"\")\n", + " sources = answer['source_documents']\n", + " print(\"-\"*150,\"\\n\")\n", + " print(f\"Question: {question}\")\n", + " print(f\"Answer: {result}\")\n", + "\n", + " ### COMMENT OUT THE 4 LINES BELOW TO HIDE THE SOURCES\n", + " print(f\"\\nSources:\")\n", + " for idx, source in enumerate(sources):\n", + " source_wrapped = tr.fill(str(source.page_content), width=150)\n", + " print(f\"{idx+1}: {source_wrapped}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bX77dCbuCxCu" + }, + "source": [ + "## Questions in French" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rg29qxkPCdJL" + }, + "outputs": [], + "source": [ + "questions_fr = [\n", + " \"À quoi se compare The Whole Earth Catalog ?\",\n", + " \"Dans quoi Reed College était-il excellent ?\",\n", + " \"De quoi l'auteur a-t-il été diagnostiqué ?\",\n", + " \"Quelle est la leçon clé de cet article ?\",\n", + " \"Que disait l'article sur Michael Jackson ?\",\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "EFuLtdgy5aZw" + }, + "outputs": [], + "source": [ + "# import langchain\n", + "# langchain.debug = False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "La7K_N7UTRdb", + "outputId": "8931bf1c-afe6-4b80-8979-841456e79a01" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "Tp_PyQ_FbG4z", - "outputId": "b7dc4c49-989e-4a25-ee73-e123f8941aa1" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Query language: English\n", - "Query: How to get in touch with Bill Gates\n", - "Most similar existing question: What is Bill Gates of Microsoft E-mail address ?\n", - "-------------------- \n", - "\n", - "Query language: French\n", - "Query: Comment entrer en contact avec Bill Gates\n", - "Most similar existing question: What is Bill Gates of Microsoft E-mail address ?\n", - "-------------------- \n", - "\n", - "Query language: Indonesian\n", - "Query: Cara menghubungi Bill Gates\n", - "Most similar existing question: What is Bill Gates of Microsoft E-mail address ?\n", - "-------------------- \n", - "\n" - ] - } + "name": "stdout", + "output_type": "stream", + "text": [ + "-------------------- \n", + "\n", + "Question: À quoi se compare The Whole Earth Catalog ?\n", + "Answer: The Whole Earth Catalog was like Google in paperback form, 35 years before Google came along.\n", + "-------------------- \n", + "\n", + "Question: Dans quoi Reed College était-il excellent ?\n", + "Answer: Reed College offered the best calligraphy instruction in the country.\n", + "-------------------- \n", + "\n", + "Question: De quoi l'auteur a-t-il été diagnostiqué ?\n", + "Answer: The author was diagnosed with a very rare form of pancreatic cancer that is curable with surgery.\n", + "-------------------- \n", + "\n", + "Question: Quelle est la leçon clé de cet article ?\n", + "Answer: The key lesson of this article is that remembering that you will die soon is the most important tool to help one make the big choices in life.\n", + "-------------------- \n", + "\n", + "Question: Que disait l'article sur Michael Jackson ?\n", + "Answer: The text does not contain the answer to the question.\n" + ] + } + ], + "source": [ + "# Generate the answer given the context\n", + "\n", + "chain_type_kwargs = {\"prompt\": PROMPT}\n", + "\n", + "qa = RetrievalQA.from_chain_type(llm=Cohere(model=\"command\", temperature=0), \n", + " chain_type=\"stuff\", \n", + " retriever=db.as_retriever(), \n", + " chain_type_kwargs=chain_type_kwargs, \n", + " return_source_documents=True)\n", + "\n", + "for question in questions_fr:\n", + " answer = qa({\"query\": question})\n", + " result = answer[\"result\"].replace(\"\\n\",\"\").replace(\"Answer:\",\"\")\n", + " sources = answer['source_documents']\n", + " print(\"-\"*20,\"\\n\")\n", + " print(f\"Question: {question}\")\n", + " print(f\"Answer: {result}\")" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "machine_shape": "hm", + "provenance": [] + }, + "gpuClass": "standard", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + }, + "vscode": { + "interpreter": { + "hash": "3a0ab37a1f07e7d320af811f0819b193749e9675a96eea7a4830e92d810d141d" + } + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "01545efb5b78418791ce0f8c763873ce": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "02e46682b2434a0c872f35db3d7b367e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "20px" + } + }, + "034072a591b94d3daf4284aadcff935f": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": null + } + }, + "09c17a96b5534b78b1d9bfc2f7bc83d5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_735bfe1c1ff6402d826257313d68b21b", + "IPY_MODEL_df1b4d3501ed457b86b60a5449d1e1da", + "IPY_MODEL_771c7097b5be45ffac31e70117376903" ], - "source": [ - "# Print the top document match for each query\n", - "for idx,query in enumerate(queries):\n", - " print(f\"Query language: {queries_lang[idx]}\")\n", - " print(f\"Query: {query}\")\n", - " print(f\"Most similar existing question: {answers[idx]}\")\n", - " print(\"-\"*20,\"\\n\")" - ] + "layout": "IPY_MODEL_996f65fcf7a04703868717652927e5e2" + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "aRpRAfLB9JhY" - }, - "source": [ - "# Example 2 - Search-Based Question Answering" - ] + "10ca522adeca4ba4bb2d4f9373a363f4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "-f2kF2vShj9S" - }, - "source": [ - "![Example-2---Search-Based-Question-Answering.png](data:image/png;base64,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)" - ] + "1385286d855a46c8b19704a95e5992b4": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5cf957caabe043139dc587e8651a28b1", + "max": 5452, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_bfb987eb24644819ba52b2fc7bc865de", + "value": 5452 + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "nV0A1Z0Z9VTc" - }, - "source": [ - "## Add an article and chunk it into smaller passages" - ] + "190a428569a74beb8b90aa278c629bd2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_6d1ea14b22034d2d9ab16aa5a24566dc", + "placeholder": "​", + "style": "IPY_MODEL_6c0193f68df143e0a7907c6a577b07a6", + "value": " 0/0 [00:04<?, ? MiB/s]" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "s12ZE7vcHRJI", - "outputId": "7ebb06e3-d39d-4c65-92cb-73be8b032d1a" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--2023-06-08 06:11:19-- https://docs.google.com/uc?export=download&id=1f1INWOfJrHTFmbyF_0be5b4u_moz3a4F\n", - "Resolving docs.google.com (docs.google.com)... 74.125.200.101, 74.125.200.138, 74.125.200.102, ...\n", - "Connecting to docs.google.com (docs.google.com)|74.125.200.101|:443... connected.\n", - "HTTP request sent, awaiting response... 303 See Other\n", - "Location: https://doc-0g-84-docs.googleusercontent.com/docs/securesc/ha0ro937gcuc7l7deffksulhg5h7mbp1/84t4moii9dmg08hmrh6rfpp8ecrjh6jq/1686204675000/12721472133292131824/*/1f1INWOfJrHTFmbyF_0be5b4u_moz3a4F?e=download&uuid=a26288c7-ad0c-4707-ae0b-72cb94c224dc [following]\n", - "Warning: wildcards not supported in HTTP.\n", - "--2023-06-08 06:11:19-- https://doc-0g-84-docs.googleusercontent.com/docs/securesc/ha0ro937gcuc7l7deffksulhg5h7mbp1/84t4moii9dmg08hmrh6rfpp8ecrjh6jq/1686204675000/12721472133292131824/*/1f1INWOfJrHTFmbyF_0be5b4u_moz3a4F?e=download&uuid=a26288c7-ad0c-4707-ae0b-72cb94c224dc\n", - "Resolving doc-0g-84-docs.googleusercontent.com (doc-0g-84-docs.googleusercontent.com)... 74.125.130.132, 2404:6800:4003:c01::84\n", - "Connecting to doc-0g-84-docs.googleusercontent.com (doc-0g-84-docs.googleusercontent.com)|74.125.130.132|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 11993 (12K) [text/plain]\n", - "Saving to: ‘steve-jobs-commencement.txt’\n", - "\n", - "steve-jobs-commence 100%[===================>] 11.71K --.-KB/s in 0s \n", - "\n", - "2023-06-08 06:11:20 (115 MB/s) - ‘steve-jobs-commencement.txt’ saved [11993/11993]\n", - "\n" - ] - } + "1ac7e3656e43480c8af4038d2e7d5432": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "1f1331ab4e734cdaa66cf28d7278f980": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "211f7336a3b9455f8cd67bd0ee4113ae": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_68bf09957e83431b8d299f1ab15d5f7e", + "placeholder": "​", + "style": "IPY_MODEL_28adfb59f3e24851ba617e0087e5293f", + "value": "Generating test examples...: 0%" + } + }, + "23bbe3c6dfcb42c7a0a1c826bc35076d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "25a079a3d58644f4a5306ee2cb42dbde": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "28adfb59f3e24851ba617e0087e5293f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2bd5fe14d3d44d85be32c5c78f5b7568": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_10ca522adeca4ba4bb2d4f9373a363f4", + "max": 500, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5f9f737d68234b9a9cd069105ab20ea2", + "value": 500 + } + }, + "2d69c8378b194aa3a8634848da5ee79a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2ee59cbc091346168c3b4511f64b018a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "35132c00838046bca253f31350a3190b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_88ff8d07f6ce430db2772b8bf24294e8", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_f5e168c246714295a10a64fbb1ef2ee3", + "value": 0 + } + }, + "3627640fb7d14ac09c9fdcbfb2159152": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_6e600a0c3f36439899b40cdc53ed7c8c", + "max": 500, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_672ec8abe8b34b8dab6d4af20f0302c7", + "value": 500 + } + }, + "3647d22aaf934b53bf925dc22e2ce69a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_89f757fbb1ef4fa8b557c04926871096", + "placeholder": "​", + "style": "IPY_MODEL_94ebb17c331649fc812a66231532ee03", + "value": " 0/0 [00:04<?, ? file/s]" + } + }, + "3948a575b3ee4a199f1055e93d8270ee": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "3bda8233967642229fe778b4a8402f52": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "3da4f3751cb54cf2938aea924ab33aa0": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "4334b4f6fc7048eab0d146b6ffc437d1": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_be8b3f4e73fc44f390e9a147df786e53", + "placeholder": "​", + "style": "IPY_MODEL_3bda8233967642229fe778b4a8402f52", + "value": "Dl Completed...: 100%" + } + }, + "463628ae5afc4c8f9a51f2c4ed038d12": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4cf6a31b3be945cbb82f8239e7e2642e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_7fd82914b89343538aa08b36f4752f4b", + "IPY_MODEL_35132c00838046bca253f31350a3190b", + "IPY_MODEL_190a428569a74beb8b90aa278c629bd2" ], - "source": [ - "# We'll use Steve Jobs' Stanford University commencement address as the example. Link: https://news.stanford.edu/2005/06/12/youve-got-find-love-jobs-says/\n", - "\n", - "!wget 'https://docs.google.com/uc?export=download&id=1f1INWOfJrHTFmbyF_0be5b4u_moz3a4F' -O steve-jobs-commencement.txt" - ] + "layout": "IPY_MODEL_01545efb5b78418791ce0f8c763873ce" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "obv6NbUcNfB_" - }, - "outputs": [], - "source": [ - "loader = TextLoader(\"steve-jobs-commencement.txt\")\n", - "documents = loader.load()\n", - "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)\n", - "texts = text_splitter.split_documents(documents)" - ] + "533f3a17f8d1442490a2d6167d89550b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "DHvoF9CB9apc" - }, - "source": [ - "## Embed the passages and store them in an index" - ] + "57cf77bba44141359639c0268ced8934": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "11Bx0k2LGIH-" - }, - "outputs": [], - "source": [ - "embeddings = CohereEmbeddings(model = \"multilingual-22-12\")\n", - "db = Qdrant.from_documents(texts, embeddings, location=\":memory:\", collection_name=\"my_documents\", distance_func=\"Dot\")" - ] + "59f2ed0257d6422d84fa23898e5d9a10": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_533f3a17f8d1442490a2d6167d89550b", + "placeholder": "​", + "style": "IPY_MODEL_ce82f835dd2b45a181a53407505b0cfc", + "value": "Extraction completed...: " + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "xQsrDUQo9poh" - }, - "source": [ - "## Enter a question" - ] + "5cf957caabe043139dc587e8651a28b1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "SW90c8kOqdow" - }, - "outputs": [], - "source": [ - "questions = [\n", - " \"What did the author liken The Whole Earth Catalog to?\",\n", - " \"What was Reed College great at?\",\n", - " \"What was the author diagnosed with?\",\n", - " \"What is the key lesson from this article?\",\n", - " \"What did the article say about Michael Jackson?\",\n", - " ]" - ] + "5ed53479e65749a68e2ae1f70fff1db0": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "HXhkK22JvNa1" - }, - "source": [ - "## Answer the question based on the most relevant documents\n" - ] + "5edafe62c55449709c304c11dc847e82": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "-dgBvF5HI9Wd" - }, - "outputs": [], - "source": [ - "# Create our own prompt template\n", - "\n", - "prompt_template = \"\"\"Text: {context}\n", - "\n", - "Question: {question}\n", - "\n", - "Answer the question based on the text provided. If the text doesn't contain the answer, reply that the answer is not available.\"\"\"\n", - "\n", - "PROMPT = PromptTemplate(\n", - " template=prompt_template, input_variables=[\"context\", \"question\"]\n", - ")" - ] + "5f9f737d68234b9a9cd069105ab20ea2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "8wa_YjzpcEAE", - "outputId": "31120ad3-034a-42f1-96a3-7454cd68ade5" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", - "\n", - "Question: What did the author liken The Whole Earth Catalog to?\n", - "Answer: It was sort of like Google in paperback form, 35 years before Google came along\n", - "\n", - "Sources:\n", - "1: When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a\n", - "fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960s, before\n", - "personal computers and desktop publishing, so it was all made with typewriters, scissors and Polaroid cameras. It was sort of like Google in paperback\n", - "form, 35 years before Google came along: It was\n", - "2: Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the\n", - "mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find\n", - "yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they\n", - "signed off. Stay Hungry. Stay Foolish. And I have always\n", - "3: idealistic, and overflowing with neat tools and great notions.\n", - "4: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", - "\n", - "Question: What was Reed College great at?\n", - "Answer: Reed College was great at calligraphy instruction.\n", - "\n", - "Sources:\n", - "1: Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every\n", - "drawer, was beautifully hand calligraphed. Because I had dropped out and didn’t have to take the normal classes, I decided to take a calligraphy class\n", - "to learn how to do this. I learned about serif and sans serif typefaces, about varying the amount of space between different letter combinations,\n", - "about what makes great typography great. It was\n", - "2: I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why\n", - "did I drop out?\n", - "3: never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they\n", - "do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backward 10 years\n", - "later.\n", - "4: OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the\n", - "required classes that didn’t interest me, and begin dropping in on the ones that looked interesting.\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", - "\n", - "Question: What was the author diagnosed with?\n", - "Answer: The author was diagnosed with cancer.\n", - "\n", - "Sources:\n", - "1: I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my\n", - "intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed\n", - "the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with\n", - "surgery. I had the surgery and I’m fine now.\n", - "2: About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn’t even know\n", - "what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than\n", - "three to six months. My doctor advised me to go home and get my affairs in order, which is doctor’s code for prepare to die. It means to try to tell\n", - "your kids everything you thought you’d have the\n", - "3: Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the\n", - "mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find\n", - "yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they\n", - "signed off. Stay Hungry. Stay Foolish. And I have always\n", - "4: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", - "\n", - "Question: What is the key lesson from this article?\n", - "Answer: The key lesson from this article is that you have to trust that the dots will somehow connect in your future. You have to trust in something -- your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.\n", - "\n", - "Sources:\n", - "1: Again, you can’t connect the dots looking forward; you can only connect them looking backward. So you have to trust that the dots will somehow connect\n", - "in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all\n", - "the difference in my life. My second story is about love and loss.\n", - "2: Remembering that I’ll be dead soon is the most important tool I’ve ever encountered to help me make the big choices in life. Because almost everything\n", - "— all external expectations, all pride, all fear of embarrassment or failure — these things just fall away in the face of death, leaving only what is\n", - "truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are\n", - "already naked. There is no reason not to follow your\n", - "3: Your time is limited, so don’t waste it living someone else’s life. Don’t be trapped by dogma — which is living with the results of other people’s\n", - "thinking. Don’t let the noise of others’ opinions drown out your own inner voice. And most important, have the courage to follow your heart and\n", - "intuition. They somehow already know what you truly want to become. Everything else is secondary.\n", - "4: I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down — that I had dropped the baton\n", - "as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and\n", - "I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple\n", - "had not changed that one bit. I had been rejected,\n", - "------------------------------------------------------------------------------------------------------------------------------------------------------ \n", - "\n", - "Question: What did the article say about Michael Jackson?\n", - "Answer: The text did not provide information about Michael Jackson.\n", - "\n", - "Sources:\n", - "1: baby boy; do you want him?” They said: “Of course.” My biological mother later found out that my mother had never graduated from college and that my\n", - "father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents\n", - "promised that I would someday go to college.\n", - "2: beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.\n", - "3: I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down — that I had dropped the baton\n", - "as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and\n", - "I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple\n", - "had not changed that one bit. I had been rejected,\n", - "4: This was the closest I’ve been to facing death, and I hope it’s the closest I get for a few more decades. Having lived through it, I can now say this\n", - "to you with a bit more certainty than when death was a useful but purely intellectual concept:\n" - ] - } + "62eb05321e2d4265b033544921f92053": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_463628ae5afc4c8f9a51f2c4ed038d12", + "placeholder": "​", + "style": "IPY_MODEL_1ac7e3656e43480c8af4038d2e7d5432", + "value": "Shuffling /root/tensorflow_datasets/trec/1.0.0.incompleteWOR5EP/trec-test.tfrecord*...: 0%" + } + }, + "65b7f23304a243878c43ea391885ee85": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c5296022707240b393be4146e983083c", + "placeholder": "​", + "style": "IPY_MODEL_8653f9b6a25446cc8d7d34ffd4e48ca8", + "value": " 1/2 [00:00<00:00, 2.06 splits/s]" + } + }, + "672ec8abe8b34b8dab6d4af20f0302c7": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "6850b87ff2fa49eb9fbfb3c3492efbb3": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d298dc9202dc49aba09b66969b3d19f9", + "placeholder": "​", + "style": "IPY_MODEL_6e09dadf883440038a7a47f0d9723ae6", + "value": " 0/500 [00:00<?, ? examples/s]" + } + }, + "687cfefc80a54edd84eb22baf805c905": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "68bf09957e83431b8d299f1ab15d5f7e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6a7d1421176f4b62af003a4b2f18815b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "6c0193f68df143e0a7907c6a577b07a6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "6d1ea14b22034d2d9ab16aa5a24566dc": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6def2ecb657845a3bae18bad85950991": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": null + } + }, + "6e09dadf883440038a7a47f0d9723ae6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "6e600a0c3f36439899b40cdc53ed7c8c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "735bfe1c1ff6402d826257313d68b21b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5edafe62c55449709c304c11dc847e82", + "placeholder": "​", + "style": "IPY_MODEL_5ed53479e65749a68e2ae1f70fff1db0", + "value": "Shuffling /root/tensorflow_datasets/trec/1.0.0.incompleteWOR5EP/trec-train.tfrecord*...: 0%" + } + }, + "771c7097b5be45ffac31e70117376903": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d9dd5b64f0ee40359a4c577f4358248f", + "placeholder": "​", + "style": "IPY_MODEL_baf658cc369745b7bad7f18302e385d9", + "value": " 0/5452 [00:00<?, ? examples/s]" + } + }, + "7c8e1e4eee714bc086c3f84eee5941fc": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_4334b4f6fc7048eab0d146b6ffc437d1", + "IPY_MODEL_c8e13e321a9a4e0b88c717a1a8065619", + "IPY_MODEL_c1f14f69e97f44598d9c4f8d789131fb" ], - "source": [ - "chain_type_kwargs = {\"prompt\": PROMPT}\n", - "\n", - "qa = RetrievalQA.from_chain_type(llm=Cohere(model=\"command\", temperature=0), \n", - " chain_type=\"stuff\", \n", - " retriever=db.as_retriever(), \n", - " chain_type_kwargs=chain_type_kwargs, \n", - " return_source_documents=True)\n", - "\n", - "for question in questions:\n", - " answer = qa({\"query\": question})\n", - " result = answer[\"result\"].replace(\"\\n\",\"\").replace(\"Answer:\",\"\")\n", - " sources = answer['source_documents']\n", - " print(\"-\"*150,\"\\n\")\n", - " print(f\"Question: {question}\")\n", - " print(f\"Answer: {result}\")\n", - "\n", - " ### COMMENT OUT THE 4 LINES BELOW TO HIDE THE SOURCES\n", - " print(f\"\\nSources:\")\n", - " for idx, source in enumerate(sources):\n", - " source_wrapped = tr.fill(str(source.page_content), width=150)\n", - " print(f\"{idx+1}: {source_wrapped}\")" - ] + "layout": "IPY_MODEL_25a079a3d58644f4a5306ee2cb42dbde" + } }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "bX77dCbuCxCu" - }, - "source": [ - "## Questions in French" - ] + "7fa8f3f5c00c493bb7283bc90c33df5e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_59f2ed0257d6422d84fa23898e5d9a10", + "IPY_MODEL_9236baef198c44ae8607c7888e899bc8", + "IPY_MODEL_3647d22aaf934b53bf925dc22e2ce69a" + ], + "layout": "IPY_MODEL_687cfefc80a54edd84eb22baf805c905" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "rg29qxkPCdJL" - }, - "outputs": [], - "source": [ - "questions_fr = [\n", - " \"À quoi se compare The Whole Earth Catalog ?\",\n", - " \"Dans quoi Reed College était-il excellent ?\",\n", - " \"De quoi l'auteur a-t-il été diagnostiqué ?\",\n", - " \"Quelle est la leçon clé de cet article ?\",\n", - " \"Que disait l'article sur Michael Jackson ?\",\n", - " ]" - ] + "7fd82914b89343538aa08b36f4752f4b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d426d4b5b86c4582a17bf21fe5f021d4", + "placeholder": "​", + "style": "IPY_MODEL_2d69c8378b194aa3a8634848da5ee79a", + "value": "Dl Size...: " + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "EFuLtdgy5aZw" - }, - "outputs": [], - "source": [ - "# import langchain\n", - "# langchain.debug = False" - ] + "85f4ab947d774115baf64332f64248bd": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": null + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "La7K_N7UTRdb", - "outputId": "8931bf1c-afe6-4b80-8979-841456e79a01" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------- \n", - "\n", - "Question: À quoi se compare The Whole Earth Catalog ?\n", - "Answer: The Whole Earth Catalog was like Google in paperback form, 35 years before Google came along.\n", - "-------------------- \n", - "\n", - "Question: Dans quoi Reed College était-il excellent ?\n", - "Answer: Reed College offered the best calligraphy instruction in the country.\n", - "-------------------- \n", - "\n", - "Question: De quoi l'auteur a-t-il été diagnostiqué ?\n", - "Answer: The author was diagnosed with a very rare form of pancreatic cancer that is curable with surgery.\n", - "-------------------- \n", - "\n", - "Question: Quelle est la leçon clé de cet article ?\n", - "Answer: The key lesson of this article is that remembering that you will die soon is the most important tool to help one make the big choices in life.\n", - "-------------------- \n", - "\n", - "Question: Que disait l'article sur Michael Jackson ?\n", - "Answer: The text does not contain the answer to the question.\n" - ] - } + "8653f9b6a25446cc8d7d34ffd4e48ca8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "88ff8d07f6ce430db2772b8bf24294e8": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "20px" + } + }, + "89f757fbb1ef4fa8b557c04926871096": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8e7d772e693c427c9bcfc7535a524979": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "9236baef198c44ae8607c7888e899bc8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_02e46682b2434a0c872f35db3d7b367e", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_3da4f3751cb54cf2938aea924ab33aa0", + "value": 0 + } + }, + "941ab80a14aa4a1bb3943dd77aca85d7": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "94ebb17c331649fc812a66231532ee03": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "996f65fcf7a04703868717652927e5e2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": null + } + }, + "9e46610e715444cbbc2f978a0acd0ed0": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "a61d6191c53e4dd2a1cbdb9826f5ae70": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_e868b829ec7a4795955034ebb8b109a6", + "IPY_MODEL_1385286d855a46c8b19704a95e5992b4", + "IPY_MODEL_b7bbc695e0f248a0ac1e79a1d546df8e" ], - "source": [ - "# Generate the answer given the context\n", - "\n", - "chain_type_kwargs = {\"prompt\": PROMPT}\n", - "\n", - "qa = RetrievalQA.from_chain_type(llm=Cohere(model=\"command\", temperature=0), \n", - " chain_type=\"stuff\", \n", - " retriever=db.as_retriever(), \n", - " chain_type_kwargs=chain_type_kwargs, \n", - " return_source_documents=True)\n", - "\n", - "for question in questions_fr:\n", - " answer = qa({\"query\": question})\n", - " result = answer[\"result\"].replace(\"\\n\",\"\").replace(\"Answer:\",\"\")\n", - " sources = answer['source_documents']\n", - " print(\"-\"*20,\"\\n\")\n", - " print(f\"Question: {question}\")\n", - " print(f\"Answer: {result}\")" - ] + "layout": "IPY_MODEL_034072a591b94d3daf4284aadcff935f" + } }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "06UhYMFdoi0A" - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "accelerator": "GPU", - "colab": { - "machine_shape": "hm", - "provenance": [] - }, - "gpuClass": "standard", - "kernelspec": { - "display_name": "Python 3.10.5 64-bit ('3.10.5')", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.10.5" - }, - "vscode": { - "interpreter": { - "hash": "3a0ab37a1f07e7d320af811f0819b193749e9675a96eea7a4830e92d810d141d" - } - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "01545efb5b78418791ce0f8c763873ce": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "02e46682b2434a0c872f35db3d7b367e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "034072a591b94d3daf4284aadcff935f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": "hidden", - "width": null - } - }, - "09c17a96b5534b78b1d9bfc2f7bc83d5": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_735bfe1c1ff6402d826257313d68b21b", - "IPY_MODEL_df1b4d3501ed457b86b60a5449d1e1da", - "IPY_MODEL_771c7097b5be45ffac31e70117376903" - ], - "layout": "IPY_MODEL_996f65fcf7a04703868717652927e5e2" - } - }, - "10ca522adeca4ba4bb2d4f9373a363f4": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "1385286d855a46c8b19704a95e5992b4": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_5cf957caabe043139dc587e8651a28b1", - "max": 5452, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_bfb987eb24644819ba52b2fc7bc865de", - "value": 5452 - } - }, - "190a428569a74beb8b90aa278c629bd2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_6d1ea14b22034d2d9ab16aa5a24566dc", - "placeholder": "​", - "style": "IPY_MODEL_6c0193f68df143e0a7907c6a577b07a6", - "value": " 0/0 [00:04<?, ? MiB/s]" - } - }, - "1ac7e3656e43480c8af4038d2e7d5432": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "1f1331ab4e734cdaa66cf28d7278f980": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "211f7336a3b9455f8cd67bd0ee4113ae": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_68bf09957e83431b8d299f1ab15d5f7e", - "placeholder": "​", - "style": "IPY_MODEL_28adfb59f3e24851ba617e0087e5293f", - "value": "Generating test examples...: 0%" - } - }, - "23bbe3c6dfcb42c7a0a1c826bc35076d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "25a079a3d58644f4a5306ee2cb42dbde": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "28adfb59f3e24851ba617e0087e5293f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "2bd5fe14d3d44d85be32c5c78f5b7568": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_10ca522adeca4ba4bb2d4f9373a363f4", - "max": 500, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_5f9f737d68234b9a9cd069105ab20ea2", - "value": 500 - } - }, - "2d69c8378b194aa3a8634848da5ee79a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "2ee59cbc091346168c3b4511f64b018a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "35132c00838046bca253f31350a3190b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_88ff8d07f6ce430db2772b8bf24294e8", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_f5e168c246714295a10a64fbb1ef2ee3", - "value": 0 - } - }, - "3627640fb7d14ac09c9fdcbfb2159152": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_6e600a0c3f36439899b40cdc53ed7c8c", - "max": 500, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_672ec8abe8b34b8dab6d4af20f0302c7", - "value": 500 - } - }, - "3647d22aaf934b53bf925dc22e2ce69a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_89f757fbb1ef4fa8b557c04926871096", - "placeholder": "​", - "style": "IPY_MODEL_94ebb17c331649fc812a66231532ee03", - "value": " 0/0 [00:04<?, ? file/s]" - } - }, - "3948a575b3ee4a199f1055e93d8270ee": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "3bda8233967642229fe778b4a8402f52": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "3da4f3751cb54cf2938aea924ab33aa0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "4334b4f6fc7048eab0d146b6ffc437d1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_be8b3f4e73fc44f390e9a147df786e53", - "placeholder": "​", - "style": "IPY_MODEL_3bda8233967642229fe778b4a8402f52", - "value": "Dl Completed...: 100%" - } - }, - "463628ae5afc4c8f9a51f2c4ed038d12": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "4cf6a31b3be945cbb82f8239e7e2642e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_7fd82914b89343538aa08b36f4752f4b", - "IPY_MODEL_35132c00838046bca253f31350a3190b", - "IPY_MODEL_190a428569a74beb8b90aa278c629bd2" - ], - "layout": "IPY_MODEL_01545efb5b78418791ce0f8c763873ce" - } - }, - "533f3a17f8d1442490a2d6167d89550b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "57cf77bba44141359639c0268ced8934": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "59f2ed0257d6422d84fa23898e5d9a10": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_533f3a17f8d1442490a2d6167d89550b", - "placeholder": "​", - "style": "IPY_MODEL_ce82f835dd2b45a181a53407505b0cfc", - "value": "Extraction completed...: " - } - }, - "5cf957caabe043139dc587e8651a28b1": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "5ed53479e65749a68e2ae1f70fff1db0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "5edafe62c55449709c304c11dc847e82": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "5f9f737d68234b9a9cd069105ab20ea2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "62eb05321e2d4265b033544921f92053": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_463628ae5afc4c8f9a51f2c4ed038d12", - "placeholder": "​", - "style": "IPY_MODEL_1ac7e3656e43480c8af4038d2e7d5432", - "value": "Shuffling /root/tensorflow_datasets/trec/1.0.0.incompleteWOR5EP/trec-test.tfrecord*...: 0%" - } - }, - "65b7f23304a243878c43ea391885ee85": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_c5296022707240b393be4146e983083c", - "placeholder": "​", - "style": "IPY_MODEL_8653f9b6a25446cc8d7d34ffd4e48ca8", - "value": " 1/2 [00:00<00:00, 2.06 splits/s]" - } - }, - "672ec8abe8b34b8dab6d4af20f0302c7": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "6850b87ff2fa49eb9fbfb3c3492efbb3": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d298dc9202dc49aba09b66969b3d19f9", - "placeholder": "​", - "style": "IPY_MODEL_6e09dadf883440038a7a47f0d9723ae6", - "value": " 0/500 [00:00<?, ? examples/s]" - } - }, - "687cfefc80a54edd84eb22baf805c905": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "68bf09957e83431b8d299f1ab15d5f7e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "6a7d1421176f4b62af003a4b2f18815b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "6c0193f68df143e0a7907c6a577b07a6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "6d1ea14b22034d2d9ab16aa5a24566dc": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "6def2ecb657845a3bae18bad85950991": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": "hidden", - "width": null - } - }, - "6e09dadf883440038a7a47f0d9723ae6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "6e600a0c3f36439899b40cdc53ed7c8c": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "735bfe1c1ff6402d826257313d68b21b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_5edafe62c55449709c304c11dc847e82", - "placeholder": "​", - "style": "IPY_MODEL_5ed53479e65749a68e2ae1f70fff1db0", - "value": "Shuffling /root/tensorflow_datasets/trec/1.0.0.incompleteWOR5EP/trec-train.tfrecord*...: 0%" - } - }, - "771c7097b5be45ffac31e70117376903": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d9dd5b64f0ee40359a4c577f4358248f", - "placeholder": "​", - "style": "IPY_MODEL_baf658cc369745b7bad7f18302e385d9", - "value": " 0/5452 [00:00<?, ? examples/s]" - } - }, - "7c8e1e4eee714bc086c3f84eee5941fc": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_4334b4f6fc7048eab0d146b6ffc437d1", - "IPY_MODEL_c8e13e321a9a4e0b88c717a1a8065619", - "IPY_MODEL_c1f14f69e97f44598d9c4f8d789131fb" - ], - "layout": "IPY_MODEL_25a079a3d58644f4a5306ee2cb42dbde" - } - }, - "7fa8f3f5c00c493bb7283bc90c33df5e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_59f2ed0257d6422d84fa23898e5d9a10", - "IPY_MODEL_9236baef198c44ae8607c7888e899bc8", - "IPY_MODEL_3647d22aaf934b53bf925dc22e2ce69a" - ], - "layout": "IPY_MODEL_687cfefc80a54edd84eb22baf805c905" - } - }, - "7fd82914b89343538aa08b36f4752f4b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d426d4b5b86c4582a17bf21fe5f021d4", - "placeholder": "​", - "style": "IPY_MODEL_2d69c8378b194aa3a8634848da5ee79a", - "value": "Dl Size...: " - } - }, - "85f4ab947d774115baf64332f64248bd": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": "hidden", - "width": null - } - }, - "8653f9b6a25446cc8d7d34ffd4e48ca8": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "88ff8d07f6ce430db2772b8bf24294e8": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "89f757fbb1ef4fa8b557c04926871096": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8e7d772e693c427c9bcfc7535a524979": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "9236baef198c44ae8607c7888e899bc8": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_02e46682b2434a0c872f35db3d7b367e", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_3da4f3751cb54cf2938aea924ab33aa0", - "value": 0 - } - }, - "941ab80a14aa4a1bb3943dd77aca85d7": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "94ebb17c331649fc812a66231532ee03": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "996f65fcf7a04703868717652927e5e2": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": "hidden", - "width": null - } - }, - "9e46610e715444cbbc2f978a0acd0ed0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "a61d6191c53e4dd2a1cbdb9826f5ae70": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_e868b829ec7a4795955034ebb8b109a6", - "IPY_MODEL_1385286d855a46c8b19704a95e5992b4", - "IPY_MODEL_b7bbc695e0f248a0ac1e79a1d546df8e" - ], - "layout": "IPY_MODEL_034072a591b94d3daf4284aadcff935f" - } - }, - "a9f4707824454e35b2273412c4586b8d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_efa03832003244a490cfcb34edf7ccbe", - "placeholder": "​", - "style": "IPY_MODEL_9e46610e715444cbbc2f978a0acd0ed0", - "value": "Generating splits...: 50%" - } - }, - "b04f406f1a2a46818d034a80d13f6664": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "b07ffeedc45a4fe9919f99d71a2ea3f2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_211f7336a3b9455f8cd67bd0ee4113ae", - "IPY_MODEL_2bd5fe14d3d44d85be32c5c78f5b7568", - "IPY_MODEL_6850b87ff2fa49eb9fbfb3c3492efbb3" - ], - "layout": "IPY_MODEL_6def2ecb657845a3bae18bad85950991" - } - }, - "b7bbc695e0f248a0ac1e79a1d546df8e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_8e7d772e693c427c9bcfc7535a524979", - "placeholder": "​", - "style": "IPY_MODEL_d646a9a4cc5a4876a7fa185bf9eb3ccf", - "value": " 0/5452 [00:00<?, ? examples/s]" - } - }, - "baf658cc369745b7bad7f18302e385d9": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "be8b3f4e73fc44f390e9a147df786e53": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "bf6033cd5d0c4ef5ac934ed6e8adaeb6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": "hidden", - "width": null - } - }, - "bfb987eb24644819ba52b2fc7bc865de": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "c05f2a082d5e4a0c8f3b9b6952eff208": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_57cf77bba44141359639c0268ced8934", - "placeholder": "​", - "style": "IPY_MODEL_6a7d1421176f4b62af003a4b2f18815b", - "value": " 0/500 [00:00<?, ? examples/s]" - } - }, - "c1f14f69e97f44598d9c4f8d789131fb": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_1f1331ab4e734cdaa66cf28d7278f980", - "placeholder": "​", - "style": "IPY_MODEL_d773c0f65a014ae08f533bf2348c1831", - "value": " 2/2 [00:04<00:00, 2.35s/ url]" - } - }, - "c37f294926f945898096874d324ee2ae": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "c5296022707240b393be4146e983083c": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "c8e13e321a9a4e0b88c717a1a8065619": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_c37f294926f945898096874d324ee2ae", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_941ab80a14aa4a1bb3943dd77aca85d7", - "value": 1 - } - }, - "cd23755e6122427e9d95eb808b7900c2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_62eb05321e2d4265b033544921f92053", - "IPY_MODEL_3627640fb7d14ac09c9fdcbfb2159152", - "IPY_MODEL_c05f2a082d5e4a0c8f3b9b6952eff208" - ], - "layout": "IPY_MODEL_bf6033cd5d0c4ef5ac934ed6e8adaeb6" - } - }, - "ce82f835dd2b45a181a53407505b0cfc": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "d24e60c7e4664e0ba11cce85c647e526": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d298dc9202dc49aba09b66969b3d19f9": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d426d4b5b86c4582a17bf21fe5f021d4": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d646a9a4cc5a4876a7fa185bf9eb3ccf": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "d773c0f65a014ae08f533bf2348c1831": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "d849ae343e51419c803c29c24a16dd01": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_3948a575b3ee4a199f1055e93d8270ee", - "max": 2, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_2ee59cbc091346168c3b4511f64b018a", - "value": 2 - } - }, - "d9dd5b64f0ee40359a4c577f4358248f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "df1b4d3501ed457b86b60a5449d1e1da": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_b04f406f1a2a46818d034a80d13f6664", - "max": 5452, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_fcc06cd646ff425b9172312808dd3e24", - "value": 5452 - } - }, - "df522159441841cda1f97d63aab5ad9e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_a9f4707824454e35b2273412c4586b8d", - "IPY_MODEL_d849ae343e51419c803c29c24a16dd01", - "IPY_MODEL_65b7f23304a243878c43ea391885ee85" - ], - "layout": "IPY_MODEL_85f4ab947d774115baf64332f64248bd" - } - }, - "e868b829ec7a4795955034ebb8b109a6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d24e60c7e4664e0ba11cce85c647e526", - "placeholder": "​", - "style": "IPY_MODEL_23bbe3c6dfcb42c7a0a1c826bc35076d", - "value": "Generating train examples...: 0%" - } - }, - "efa03832003244a490cfcb34edf7ccbe": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "f5e168c246714295a10a64fbb1ef2ee3": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "fcc06cd646ff425b9172312808dd3e24": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - } - } + "a9f4707824454e35b2273412c4586b8d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_efa03832003244a490cfcb34edf7ccbe", + "placeholder": "​", + "style": "IPY_MODEL_9e46610e715444cbbc2f978a0acd0ed0", + "value": "Generating splits...: 50%" + } + }, + "b04f406f1a2a46818d034a80d13f6664": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b07ffeedc45a4fe9919f99d71a2ea3f2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_211f7336a3b9455f8cd67bd0ee4113ae", + "IPY_MODEL_2bd5fe14d3d44d85be32c5c78f5b7568", + "IPY_MODEL_6850b87ff2fa49eb9fbfb3c3492efbb3" + ], + "layout": "IPY_MODEL_6def2ecb657845a3bae18bad85950991" + } + }, + "b7bbc695e0f248a0ac1e79a1d546df8e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_8e7d772e693c427c9bcfc7535a524979", + "placeholder": "​", + "style": "IPY_MODEL_d646a9a4cc5a4876a7fa185bf9eb3ccf", + "value": " 0/5452 [00:00<?, ? examples/s]" + } + }, + "baf658cc369745b7bad7f18302e385d9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "be8b3f4e73fc44f390e9a147df786e53": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "bf6033cd5d0c4ef5ac934ed6e8adaeb6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": null + } + }, + "bfb987eb24644819ba52b2fc7bc865de": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "c05f2a082d5e4a0c8f3b9b6952eff208": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_57cf77bba44141359639c0268ced8934", + "placeholder": "​", + "style": "IPY_MODEL_6a7d1421176f4b62af003a4b2f18815b", + "value": " 0/500 [00:00<?, ? examples/s]" + } + }, + "c1f14f69e97f44598d9c4f8d789131fb": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_1f1331ab4e734cdaa66cf28d7278f980", + "placeholder": "​", + "style": "IPY_MODEL_d773c0f65a014ae08f533bf2348c1831", + "value": " 2/2 [00:04<00:00, 2.35s/ url]" + } + }, + "c37f294926f945898096874d324ee2ae": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "20px" + } + }, + "c5296022707240b393be4146e983083c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c8e13e321a9a4e0b88c717a1a8065619": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c37f294926f945898096874d324ee2ae", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_941ab80a14aa4a1bb3943dd77aca85d7", + "value": 1 + } + }, + "cd23755e6122427e9d95eb808b7900c2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_62eb05321e2d4265b033544921f92053", + "IPY_MODEL_3627640fb7d14ac09c9fdcbfb2159152", + "IPY_MODEL_c05f2a082d5e4a0c8f3b9b6952eff208" + ], + "layout": "IPY_MODEL_bf6033cd5d0c4ef5ac934ed6e8adaeb6" + } + }, + "ce82f835dd2b45a181a53407505b0cfc": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d24e60c7e4664e0ba11cce85c647e526": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d298dc9202dc49aba09b66969b3d19f9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d426d4b5b86c4582a17bf21fe5f021d4": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d646a9a4cc5a4876a7fa185bf9eb3ccf": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d773c0f65a014ae08f533bf2348c1831": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d849ae343e51419c803c29c24a16dd01": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_3948a575b3ee4a199f1055e93d8270ee", + "max": 2, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_2ee59cbc091346168c3b4511f64b018a", + "value": 2 + } + }, + "d9dd5b64f0ee40359a4c577f4358248f": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "df1b4d3501ed457b86b60a5449d1e1da": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_b04f406f1a2a46818d034a80d13f6664", + "max": 5452, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_fcc06cd646ff425b9172312808dd3e24", + "value": 5452 + } + }, + "df522159441841cda1f97d63aab5ad9e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_a9f4707824454e35b2273412c4586b8d", + "IPY_MODEL_d849ae343e51419c803c29c24a16dd01", + "IPY_MODEL_65b7f23304a243878c43ea391885ee85" + ], + "layout": "IPY_MODEL_85f4ab947d774115baf64332f64248bd" + } + }, + "e868b829ec7a4795955034ebb8b109a6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d24e60c7e4664e0ba11cce85c647e526", + "placeholder": "​", + "style": "IPY_MODEL_23bbe3c6dfcb42c7a0a1c826bc35076d", + "value": "Generating train examples...: 0%" + } + }, + "efa03832003244a490cfcb34edf7ccbe": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "f5e168c246714295a10a64fbb1ef2ee3": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "fcc06cd646ff425b9172312808dd3e24": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } } - }, - "nbformat": 4, - "nbformat_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/notebooks/guides/QuestionAnwering_Cohere_SagemakerJumpstart.ipynb b/notebooks/guides/QuestionAnwering_Cohere_SagemakerJumpstart.ipynb index d5caa6c4..ddc32d16 100644 --- a/notebooks/guides/QuestionAnwering_Cohere_SagemakerJumpstart.ipynb +++ b/notebooks/guides/QuestionAnwering_Cohere_SagemakerJumpstart.ipynb @@ -1,7 +1,6 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -9,7 +8,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -17,7 +15,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -31,7 +28,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -46,7 +42,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -62,7 +57,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -80,6 +74,7 @@ "cell_type": "code", "execution_count": null, "metadata": { + "collapsed": true, "jupyter": { "outputs_hidden": true }, @@ -125,7 +120,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -194,7 +188,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] @@ -263,7 +256,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -333,7 +325,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -341,7 +332,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -389,7 +379,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -399,7 +388,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -430,7 +418,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -495,7 +482,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -547,7 +533,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -571,7 +556,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -600,7 +584,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -660,7 +643,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -693,19 +675,17 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "**Now, we can build an QA application. LangChain makes it extremly simple with following few lines of code.**" + "**Now, we can build an QA application. LangChain makes it extremely simple with following few lines of code.**" ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Based on the question below, we can achieven the points in Step 4 with just a few lines of code as shown below." + "Based on the question below, we can achieve the points in Step 4 with just a few lines of code as shown below." ] }, { @@ -757,7 +737,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -767,7 +746,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -797,7 +775,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -816,7 +793,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -835,7 +811,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -869,7 +844,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -890,7 +864,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -909,7 +882,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -950,7 +922,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [] @@ -1534,9 +1505,9 @@ ], "instance_type": "ml.t3.medium", "kernelspec": { - "display_name": "Python 3 (PyTorch 1.13 Python 3.9 CPU Optimized)", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/pytorch-1.13-cpu-py39" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -1548,7 +1519,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/guides/Recipes_for_better_meeting_notes_summary.ipynb b/notebooks/guides/Recipes_for_better_meeting_notes_summary.ipynb index a2defd0e..bf0dc430 100644 --- a/notebooks/guides/Recipes_for_better_meeting_notes_summary.ipynb +++ b/notebooks/guides/Recipes_for_better_meeting_notes_summary.ipynb @@ -1,15 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: we are in the process of updating the links in this notebook. If a link doesn't work, please open an issue and we'll rectify it ASAP. Thanks for your understanding!\n", - "\n", - "Links to add:\n", - "* Cell 1: full system for auto-meeting notes" - ] - }, { "cell_type": "markdown", "metadata": { @@ -28,7 +18,7 @@ "\n", "Finally, we'll show that prompting the model for 1.-3. can be combined with the formatting instructions covered from our previous guide.\n", "\n", - "We're constantly improving our summarisation capabilities across domains. For more information, you can reach out to us at summarize@cohere.com.\n", + "We're constantly improving our summarisation capabilities across domains. For more information, you can reach out to us [using this link](https://cohere.com/contact-sales).\n", "\n" ] }, @@ -56,8 +46,8 @@ "outputs": [], "source": [ "%%capture\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" datasets tokenizers\n", + "# TODO: upgrade to \"cohere>5\"\n", + "!pip install \"cohere<5\" datasets tokenizers\n", "\n", "import cohere\n", "from getpass import getpass\n", diff --git a/notebooks/guides/Summarization_Evals.ipynb b/notebooks/guides/Summarization_Evals.ipynb index 9c7c74b0..0d529664 100644 --- a/notebooks/guides/Summarization_Evals.ipynb +++ b/notebooks/guides/Summarization_Evals.ipynb @@ -1,21 +1,12 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "WClxySHIzi9G" - }, - "source": [ - "![Cohere-Logo-Color-RGB.png](data:image/png;base64,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)" - ] - }, { "cell_type": "markdown", "metadata": { "id": "LplM9PSe8djM" }, "source": [ - "# Evaluating summarization\n", + "# Summarization Evals\n", "\n", "In this cookbook, we will be demonstrating an approach we use for evaluating summarization tasks using LLM evaluation.\n", "\n", @@ -34,26 +25,26 @@ "source": [ "\n", "\n", - "# Get Started\n", + "## Get Started\n", "\n", "You'll need a Cohere API key to run this notebook. If you don't have a key, head to https://cohere.com/ to generate your key." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "id": "H2TfKiPM3a6f" }, "outputs": [], "source": [ "# %%capture\n", - "!pip install \"cohere<5\" datasets --quiet" + "!pip install cohere datasets --quiet" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "id": "J1HzGqnY74bj" }, @@ -86,11 +77,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "id": "1JfU70r113wo" }, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "97a7a77756614778a3d9af18eb0a7d5e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Generating train split: 0%| | 0/1095 [00:00\n", "\n", - "# Construct the evaluation dataset\n", + "## Construct the evaluation dataset\n", "\n", "We are interested in evaluating summarization in real-world, enterprise use cases, which typically have two distinguishing features as compared to academic summarization benchmarks:\n", "- Enterprise use cases often focus on specific summarization objectives, e.g. \"summarize action items\".\n", @@ -120,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "id": "2Bj2I0If13wp" }, @@ -144,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "id": "4uMI5VXm13wp" }, @@ -212,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -276,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "id": "LYTMTFAm13wr" }, @@ -296,7 +330,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "id": "igP0-oHN13wr" }, @@ -308,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -382,7 +416,7 @@ "source": [ "\n", "\n", - "# Build the evaluation framework\n", + "## Build the evaluation framework\n", "\n", "We now setup the tools we will use for evaluation.\n", "\n", @@ -396,7 +430,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "id": "KGQQp2Yd13wr" }, @@ -467,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "id": "i1niSoI-13wr" }, @@ -561,7 +595,7 @@ "source": [ "\n", "\n", - "# Run evaluations\n", + "## Run evaluations\n", "\n", "Now that we have our evaluation dataset and defined our evaluation functions, let's run evaluations!\n", "\n", @@ -570,7 +604,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "id": "HzbOQmWE13ws" }, @@ -586,7 +620,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -599,7 +633,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "PhD student D presented their method for detecting and counting acoustic events in recorded speech sessions, including speech overlaps and silence. The team sought clarification on D's definitions and counted events, discussing the challenges of distinguishing between different types of events.\n" + "PhD D is transcribing recorded sessions to locate overlapping speech zones and categorizing them as acoustic events. The team discusses the parameters PhD D should use and how to define these events, considering the number of speakers and silence.\n" ] } ], @@ -619,7 +653,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "id": "6XesZHCN13ws" }, @@ -659,7 +693,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -671,15 +705,8 @@ "outputs": [ { "data": { - "application/vnd.google.colaboratory.intrinsic+json": { - "summary": "{\n \"name\": \"data\",\n \"rows\": 6,\n \"fields\": [\n {\n \"column\": \"instruction\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 6,\n \"samples\": [\n \"Summarize the meeting based on the transcript. In paragraph form, output your response. Use at least 10 words and at most 50 words in total.\",\n \"Summarize the meeting based on the transcript. Return the answer in the form of paragraphs. Make sure your answer is between 50 and 200 words long.\",\n \"What are the follow-up items based on the meeting transcript? In bullets, output your response. Make sure to use exactly 2 bullets. Make sure each bullet is between 20 and 80 words long.\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"eval_metadata\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"objective\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 2,\n \"samples\": [\n \"action_items\",\n \"general_summarization\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"transcript\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 6,\n \"samples\": [\n \"PhD F: As opposed to the rest of us \\nPhD D: Well comment OK I I remind that me my first objective eh in the project is to to study difference parameters to to find a a good solution to detect eh the overlapping zone in eh speech recorded But eh tsk comment ehhh comment In that way comment I I I begin to to study and to analyze the ehn the recorded speech eh the different session to to find and to locate and to mark eh the the different overlapping zone And eh so eh I was eh I am transcribing the the first session and I I have found eh eh one thousand acoustic events eh besides the overlapping zones eh I I I mean the eh breaths eh aspiration eh eh talk eh eh clap eh comment I do not know what is the different names eh you use to to name the the pause n speech \\nGrad G: Oh I do not think we ve been doing it at that level of detail So \\nPhD D: Eh I I I do I do not need to to to mmm to m to label the the different acoustic but I prefer because eh I would like to to study if eh I I will find eh eh a good eh parameters eh to detect overlapping I would like to to to test these parameters eh with the another eh eh acoustic events to nnn to eh to find what is the ehm the false eh the false eh hypothesis eh nnn which eh are produced when we use the the ehm this eh parameter eh I mean pitch eh eh difference eh feature \\nPhD A: You know I think some of these that are the nonspeech overlapping events may be difficult even for humans to tell that there s two there I mean if it s a tapping sound you would not necessarily or you know something like that it would be it might be hard to know that it was two separate events \\nGrad G: Well You were not talking about just overlaps were you ? You were just talking about acoustic events \\nPhD D: I I I I t I t I talk eh about eh acoustic events in general but eh my my objective eh will be eh to study eh overlapping zone Eh ? comment n Eh in twelve minutes I found eh eh one thousand acoustic events \\nProfessor E: How many overlaps were there in it ? No no how many of them were the overlaps of speech though ? \\nPhD D: How many ? Eh almost eh three hundred eh in one session in five eh in forty five minutes Alm Three hundred overlapping zone With the overlapping zone overlapping speech speech what eh different duration \\nPostdoc B: Does this ? So if you had an overlap involving three people how many times was that counted ? \\nPhD D: three people two people Eh I would like to consider eh one people with difference noise eh in the background be \\nProfessor E: No no but I think what she s asking is pause if at some particular for some particular stretch you had three people talking instead of two did you call that one event ? \\nPhD D: Oh Oh I consider one event eh for th for that eh for all the zone This th I I I con I consider I consider eh an acoustic event the overlapping zone the period where three speaker or eh are talking together \\nGrad G: So let s say me and Jane are talking at the same time and then Liz starts talking also over all of us How many events would that be ? \\nPhD D: So I do not understand \\nGrad G: So two people are talking comment and then a third person starts talking Is there an event right here ? \\nPhD D: Eh no No no For me is the overlapping zone because because you you have s you have more one eh more one voice eh eh produced in a in in a moment \\nGrad G: So i if two or more people are talking \\nProfessor E: OK So I think We just wanted to understand how you are defining it So then in the region between since there there is some continuous region in between regions where there is only one person speaking And one contiguous region like that you are calling an event Is it Are you calling the beginning or the end of it the event or are you calling the entire length of it the event ? \\nPhD D: I consider the the nnn the nnn nnn eh the entirety eh eh all all the time there were the voice has overlapped This is the idea But eh I I do not distinguish between the the numbers of eh speaker I m not considering eh the the ehm eh the fact of eh eh for example what did you say ? Eh at first eh eh two talkers are eh speaking and eh eh a third person eh join to to that For me it s eh it s eh all overlap zone with eh several numbers of speakers is eh eh the same acoustic event Wi but without any mark between the zone of the overlapping zone with two speakers eh speaking together and the zone with the three speakers \\nPostdoc B: That would j just be one \\nPhD D: Eh with eh a beginning mark and the ending mark Because eh for me is the is the zone with eh some kind of eh distortion the spectral I do not mind By the moment by the moment \\nGrad G: Well but But you could imagine that three people talking has a different spectral characteristic than two \\nPhD D: I I do not but eh but eh I have to study comment What will happen in a general way \\nGrad G: So You had to start somewhere \\nPhD C: So there s a lot of overlap \\nPhD D: I I do not know what eh will will happen with the \\nGrad G: That s a lot of overlap \\nProfessor E: So again that s that s three three hundred in forty five minutes that are that are speakers just speakers \\nPostdoc B: But a a a th \\nProfessor E: So that s about eight per minute \\nPostdoc B: But a thousand events in twelve minutes that s \\nPhD C: But that can include taps \\nPostdoc B: Well but a thousand taps in eight minutes is a l in twelve minutes is a lot \\nPhD D: I I con I consider I consider acoustic events eh the silent too \\nGrad G: Silence starting or silence ending \\nPhD D: silent ground to bec to detect eh because I consider acoustic event all the things are not eh speech In ge in in in a general point of view \\nProfessor E: OK so how many of those thousand were silence ? \\nPhD F: Not speech not speech or too much speech \\nProfessor E: Right So how many of those thousand were silence silent sections ? \\nPhD D: silent I I I I do not I I have not the eh I I would like to to do a stylistic study\",\n \"Lynne Neagle AM: Thank you very much And the next questions then are from Suzy Davies \\nSuzy Davies AM: Thank you Chair I just wanted to have a quick answer from probably the Minister I think about the primary legislation and the regulations that followed about which childrens rights impact assessments have been done Have any been done and can they be shared with the committee if they have ? Sorry Deputy Minister\\u2014my mistake \\nJulie Morgan AM: Well it is been a very difficult time as you appreciate in terms of having to make legislation very quickly and it has not been possible to do the impact assessments that we would normally do However I am very pleased to say that we are actually launching a survey of children We are going to be launching it next week And this is to try to get from children their views of what is happened what we have been doing and their views on the whole COVID19 situation So we are doing this in conjunction with the childrens commissioner and with Young Wales and with the Youth Parliament So this is an online survey that we hope will be going out to thousands of children and we will get their response in terms of what are the important issues that have arisen for them what they feel about what is happened during this period what they feel about the way that we have dealt with the schools the way that they have had to cope in not going school and being at home for so long And so we are trying to get feedback from young people So I am very pleased that we are doing that but in terms of an impact assessment it has been very difficult as I am sure you can imagine to be able to do those at these times I think that Albert wants to come in on that \\nSuzy Davies AM: Yes because I will pursue that in a sec \\nAlbert Heaney: Thank you Thank you Chair and I think Nicola indicated before me so apologies Nicola Just to say for the committee really importantly that we have not introduced any easements in relation to childrens services legislation I think that is really quite crucial So from a Welsh context the standards that are in place do remain so therefore there would not have been a necessity for us to do a childrens rights impact assessment in relation to the primary legislation I think that is particularly a strong point to us in Wales both in terms of safeguarding arrangements but also ensuring that childrens rights are protected at a crucial time \\nNicola Edwards: Thanks In terms of childcare and education we are obviously looking at the provisions under the coronavirus Act to allow us to maybe ease some of the statutory requirements and we are going to be undertaking a full suite of impact assessments on those Obviously the coronavirus Act itself was UK Government legislation and they ran their own impact assessments but in terms of how we implement it in the childcare and education space\\u2014and I think Albert was just saying the same thing\\u2014we definitely will be looking at those impacts in terms of going forward \\nSuzy Davies AM: Well just to come back on that then are you saying to me that as a result of the various coronavirus regulations that we have had no assessments for childrens needs have been postponed cancelled or done very quickly online rather than in person ? \\nJulie Morgan AM: Well I think as Albert said that there was no relaxation of regulation for childrens social care You know that is\\u2014there have not been any in Wales \\nSuzy Davies AM: No but that is what\\u2014 There is no relaxation but what is happening in practice ? We are down on staff across all our councils and in our third sectors\\u2014who is doing the childrens needs assessments particularly for young carers ? \\nJulie Morgan AM: Well I\\u2014 Albert can you answer that ? \\nAlbert Heaney: I think the first thing to say to the committee is that going back we took a very strong line at the beginning that we were not going to introduce easements in requirements to childrens social services Of course through the way that practitioners and social work practitioners have to operate they are having to operate through a different time So assessments are still taking place for child protection and safeguarding concerns assessments are still taking place and especially in relation to\\u2014as you mentioned\\u2014young carers to support their needs So arrangements\\u2014Inaudible But they are having to be slightly differently done\\u2014so some of the technology and keeping in contact and keeping those visits So we have used for example the St Davids Day fund to make sure that care leavers are well supported in terms of having contact and are accessible and able to engage as well So we are having to be a little bit more\\u2014and social services departments are having to be a little bit more\\u2014innovative in the use of technology in the way that they have engaged as well But personal visits are taking place and visits especially as the Minister mentioned earlier on\\u2014they actually individually assess each case to determine the frequency of visits to make sure that those contacts are maintained with children at a critical time \\nSuzy Davies AM: Thank you I do not want to take this much further but personal visits and social distancing could be slightly problematic I just want to finish with this one question if I may We have had recommendations from the Carers Trust or Carers Trust Wales Have they been accepted by Government and is it those that are driving the agenda of the task and finish group that you announced the other day Deputy Minister ? \\nJulie Morgan AM: Well those will certainly be considered by the task and finish group I have had a letter from the Carers Trust about those issues and we are setting up this group as you know and we will be looking at those issues in the group \\nSuzy Davies AM: Thank you Any steal on when that might report ? \\nJulie Morgan AM: I do not have that at the moment \\nLynne Neagle AM: Maybe we could have a note on that Deputy Minister Can I just say we are running short of time ? We did start late so if the Ministers are happy we will carry on until 210 pm\\u2014310 pm\\u2014if that is And the next questions are from Si\\u00e2n Gwenllian Hold on a sec Si\\u00e2n we have lost translation again Can we just see what can be done to get the translation back ? Sorry Si\\u00e2n Is there anyone who can help with the translation ? There you go Si\\u00e2n Thank you \\nSian Gwenllian AM: You will know Deputy Minister\\u2014because we have discussed this in private session\\u2014my major concerns with regard to the childcare sector and what kind of childcare sector we will have at the end of this crisis as families start to return to the workplace There are still some childcare providers who are falling between the cracks and are not receiving financial support Do you agree\\u2014are there people who are still not being supported and why is not the Welsh Government able to provide that support for everyone in the childcare sector ? \\nJulie Morgan AM: Thank you Si\\u00e2n for that question And I know that we have had a discussion about this before Basically we are aware that there are some sectors in the childcare sector that do fall through some of the loops We have guaranteed that we will pay the money for the childcare offer for three months So that is guaranteed to them and they are able to take advantage of the Governments job retainer scheme but that does mean that there is a problem as I think we have discussed before of the double funding issue and that is something that we have been trying to resolve and there have been discussions with the Treasury in Whitehall about ways forward on this I am going to ask Nicola to come in in a minute because she is much more up to date with the discussions about that but so far I do not think very much progress has been made on that But we are looking to see if there are any other ways that we can get help to the childcare sector and I am actually following this meeting with a meeting with the Deputy Minister for equality and chief whip who is responsible for the voluntary sector because obviously many of the groups that we are talking about would come under the voluntary sector because they have voluntary committees but they fall between many stools because they rent premises rather than own premises and they do not have high turnovers that would qualify them for some of these grants So perhaps I could ask Nicola to come in to expand on that\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"prompt\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 6,\n \"samples\": [\n \"## meeting transcript\\nPhD F: As opposed to the rest of us \\nPhD D: Well comment OK I I remind that me my first objective eh in the project is to to study difference parameters to to find a a good solution to detect eh the overlapping zone in eh speech recorded But eh tsk comment ehhh comment In that way comment I I I begin to to study and to analyze the ehn the recorded speech eh the different session to to find and to locate and to mark eh the the different overlapping zone And eh so eh I was eh I am transcribing the the first session and I I have found eh eh one thousand acoustic events eh besides the overlapping zones eh I I I mean the eh breaths eh aspiration eh eh talk eh eh clap eh comment I do not know what is the different names eh you use to to name the the pause n speech \\nGrad G: Oh I do not think we ve been doing it at that level of detail So \\nPhD D: Eh I I I do I do not need to to to mmm to m to label the the different acoustic but I prefer because eh I would like to to study if eh I I will find eh eh a good eh parameters eh to detect overlapping I would like to to to test these parameters eh with the another eh eh acoustic events to nnn to eh to find what is the ehm the false eh the false eh hypothesis eh nnn which eh are produced when we use the the ehm this eh parameter eh I mean pitch eh eh difference eh feature \\nPhD A: You know I think some of these that are the nonspeech overlapping events may be difficult even for humans to tell that there s two there I mean if it s a tapping sound you would not necessarily or you know something like that it would be it might be hard to know that it was two separate events \\nGrad G: Well You were not talking about just overlaps were you ? You were just talking about acoustic events \\nPhD D: I I I I t I t I talk eh about eh acoustic events in general but eh my my objective eh will be eh to study eh overlapping zone Eh ? comment n Eh in twelve minutes I found eh eh one thousand acoustic events \\nProfessor E: How many overlaps were there in it ? No no how many of them were the overlaps of speech though ? \\nPhD D: How many ? Eh almost eh three hundred eh in one session in five eh in forty five minutes Alm Three hundred overlapping zone With the overlapping zone overlapping speech speech what eh different duration \\nPostdoc B: Does this ? So if you had an overlap involving three people how many times was that counted ? \\nPhD D: three people two people Eh I would like to consider eh one people with difference noise eh in the background be \\nProfessor E: No no but I think what she s asking is pause if at some particular for some particular stretch you had three people talking instead of two did you call that one event ? \\nPhD D: Oh Oh I consider one event eh for th for that eh for all the zone This th I I I con I consider I consider eh an acoustic event the overlapping zone the period where three speaker or eh are talking together \\nGrad G: So let s say me and Jane are talking at the same time and then Liz starts talking also over all of us How many events would that be ? \\nPhD D: So I do not understand \\nGrad G: So two people are talking comment and then a third person starts talking Is there an event right here ? \\nPhD D: Eh no No no For me is the overlapping zone because because you you have s you have more one eh more one voice eh eh produced in a in in a moment \\nGrad G: So i if two or more people are talking \\nProfessor E: OK So I think We just wanted to understand how you are defining it So then in the region between since there there is some continuous region in between regions where there is only one person speaking And one contiguous region like that you are calling an event Is it Are you calling the beginning or the end of it the event or are you calling the entire length of it the event ? \\nPhD D: I consider the the nnn the nnn nnn eh the entirety eh eh all all the time there were the voice has overlapped This is the idea But eh I I do not distinguish between the the numbers of eh speaker I m not considering eh the the ehm eh the fact of eh eh for example what did you say ? Eh at first eh eh two talkers are eh speaking and eh eh a third person eh join to to that For me it s eh it s eh all overlap zone with eh several numbers of speakers is eh eh the same acoustic event Wi but without any mark between the zone of the overlapping zone with two speakers eh speaking together and the zone with the three speakers \\nPostdoc B: That would j just be one \\nPhD D: Eh with eh a beginning mark and the ending mark Because eh for me is the is the zone with eh some kind of eh distortion the spectral I do not mind By the moment by the moment \\nGrad G: Well but But you could imagine that three people talking has a different spectral characteristic than two \\nPhD D: I I do not but eh but eh I have to study comment What will happen in a general way \\nGrad G: So You had to start somewhere \\nPhD C: So there s a lot of overlap \\nPhD D: I I do not know what eh will will happen with the \\nGrad G: That s a lot of overlap \\nProfessor E: So again that s that s three three hundred in forty five minutes that are that are speakers just speakers \\nPostdoc B: But a a a th \\nProfessor E: So that s about eight per minute \\nPostdoc B: But a thousand events in twelve minutes that s \\nPhD C: But that can include taps \\nPostdoc B: Well but a thousand taps in eight minutes is a l in twelve minutes is a lot \\nPhD D: I I con I consider I consider acoustic events eh the silent too \\nGrad G: Silence starting or silence ending \\nPhD D: silent ground to bec to detect eh because I consider acoustic event all the things are not eh speech In ge in in in a general point of view \\nProfessor E: OK so how many of those thousand were silence ? \\nPhD F: Not speech not speech or too much speech \\nProfessor E: Right So how many of those thousand were silence silent sections ? \\nPhD D: silent I I I I do not I I have not the eh I I would like to to do a stylistic study\\n\\n## instructions\\nSummarize the meeting based on the transcript. In paragraph form, output your response. Use at least 10 words and at most 50 words in total.\",\n \"## meeting transcript\\nLynne Neagle AM: Thank you very much And the next questions then are from Suzy Davies \\nSuzy Davies AM: Thank you Chair I just wanted to have a quick answer from probably the Minister I think about the primary legislation and the regulations that followed about which childrens rights impact assessments have been done Have any been done and can they be shared with the committee if they have ? Sorry Deputy Minister\\u2014my mistake \\nJulie Morgan AM: Well it is been a very difficult time as you appreciate in terms of having to make legislation very quickly and it has not been possible to do the impact assessments that we would normally do However I am very pleased to say that we are actually launching a survey of children We are going to be launching it next week And this is to try to get from children their views of what is happened what we have been doing and their views on the whole COVID19 situation So we are doing this in conjunction with the childrens commissioner and with Young Wales and with the Youth Parliament So this is an online survey that we hope will be going out to thousands of children and we will get their response in terms of what are the important issues that have arisen for them what they feel about what is happened during this period what they feel about the way that we have dealt with the schools the way that they have had to cope in not going school and being at home for so long And so we are trying to get feedback from young people So I am very pleased that we are doing that but in terms of an impact assessment it has been very difficult as I am sure you can imagine to be able to do those at these times I think that Albert wants to come in on that \\nSuzy Davies AM: Yes because I will pursue that in a sec \\nAlbert Heaney: Thank you Thank you Chair and I think Nicola indicated before me so apologies Nicola Just to say for the committee really importantly that we have not introduced any easements in relation to childrens services legislation I think that is really quite crucial So from a Welsh context the standards that are in place do remain so therefore there would not have been a necessity for us to do a childrens rights impact assessment in relation to the primary legislation I think that is particularly a strong point to us in Wales both in terms of safeguarding arrangements but also ensuring that childrens rights are protected at a crucial time \\nNicola Edwards: Thanks In terms of childcare and education we are obviously looking at the provisions under the coronavirus Act to allow us to maybe ease some of the statutory requirements and we are going to be undertaking a full suite of impact assessments on those Obviously the coronavirus Act itself was UK Government legislation and they ran their own impact assessments but in terms of how we implement it in the childcare and education space\\u2014and I think Albert was just saying the same thing\\u2014we definitely will be looking at those impacts in terms of going forward \\nSuzy Davies AM: Well just to come back on that then are you saying to me that as a result of the various coronavirus regulations that we have had no assessments for childrens needs have been postponed cancelled or done very quickly online rather than in person ? \\nJulie Morgan AM: Well I think as Albert said that there was no relaxation of regulation for childrens social care You know that is\\u2014there have not been any in Wales \\nSuzy Davies AM: No but that is what\\u2014 There is no relaxation but what is happening in practice ? We are down on staff across all our councils and in our third sectors\\u2014who is doing the childrens needs assessments particularly for young carers ? \\nJulie Morgan AM: Well I\\u2014 Albert can you answer that ? \\nAlbert Heaney: I think the first thing to say to the committee is that going back we took a very strong line at the beginning that we were not going to introduce easements in requirements to childrens social services Of course through the way that practitioners and social work practitioners have to operate they are having to operate through a different time So assessments are still taking place for child protection and safeguarding concerns assessments are still taking place and especially in relation to\\u2014as you mentioned\\u2014young carers to support their needs So arrangements\\u2014Inaudible But they are having to be slightly differently done\\u2014so some of the technology and keeping in contact and keeping those visits So we have used for example the St Davids Day fund to make sure that care leavers are well supported in terms of having contact and are accessible and able to engage as well So we are having to be a little bit more\\u2014and social services departments are having to be a little bit more\\u2014innovative in the use of technology in the way that they have engaged as well But personal visits are taking place and visits especially as the Minister mentioned earlier on\\u2014they actually individually assess each case to determine the frequency of visits to make sure that those contacts are maintained with children at a critical time \\nSuzy Davies AM: Thank you I do not want to take this much further but personal visits and social distancing could be slightly problematic I just want to finish with this one question if I may We have had recommendations from the Carers Trust or Carers Trust Wales Have they been accepted by Government and is it those that are driving the agenda of the task and finish group that you announced the other day Deputy Minister ? \\nJulie Morgan AM: Well those will certainly be considered by the task and finish group I have had a letter from the Carers Trust about those issues and we are setting up this group as you know and we will be looking at those issues in the group \\nSuzy Davies AM: Thank you Any steal on when that might report ? \\nJulie Morgan AM: I do not have that at the moment \\nLynne Neagle AM: Maybe we could have a note on that Deputy Minister Can I just say we are running short of time ? We did start late so if the Ministers are happy we will carry on until 210 pm\\u2014310 pm\\u2014if that is And the next questions are from Si\\u00e2n Gwenllian Hold on a sec Si\\u00e2n we have lost translation again Can we just see what can be done to get the translation back ? Sorry Si\\u00e2n Is there anyone who can help with the translation ? There you go Si\\u00e2n Thank you \\nSian Gwenllian AM: You will know Deputy Minister\\u2014because we have discussed this in private session\\u2014my major concerns with regard to the childcare sector and what kind of childcare sector we will have at the end of this crisis as families start to return to the workplace There are still some childcare providers who are falling between the cracks and are not receiving financial support Do you agree\\u2014are there people who are still not being supported and why is not the Welsh Government able to provide that support for everyone in the childcare sector ? \\nJulie Morgan AM: Thank you Si\\u00e2n for that question And I know that we have had a discussion about this before Basically we are aware that there are some sectors in the childcare sector that do fall through some of the loops We have guaranteed that we will pay the money for the childcare offer for three months So that is guaranteed to them and they are able to take advantage of the Governments job retainer scheme but that does mean that there is a problem as I think we have discussed before of the double funding issue and that is something that we have been trying to resolve and there have been discussions with the Treasury in Whitehall about ways forward on this I am going to ask Nicola to come in in a minute because she is much more up to date with the discussions about that but so far I do not think very much progress has been made on that But we are looking to see if there are any other ways that we can get help to the childcare sector and I am actually following this meeting with a meeting with the Deputy Minister for equality and chief whip who is responsible for the voluntary sector because obviously many of the groups that we are talking about would come under the voluntary sector because they have voluntary committees but they fall between many stools because they rent premises rather than own premises and they do not have high turnovers that would qualify them for some of these grants So perhaps I could ask Nicola to come in to expand on that\\n\\n## instructions\\nSummarize the meeting based on the transcript. Return the answer in the form of paragraphs. Make sure your answer is between 50 and 200 words long.\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"transcript_token_len\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 568,\n \"min\": 1100,\n \"max\": 2618,\n \"num_unique_values\": 6,\n \"samples\": [\n 1378,\n 1649\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"completion\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 6,\n \"samples\": [\n \"PhD student D presented their method for detecting and counting acoustic events in recorded speech sessions, including speech overlaps and silence. The team sought clarification on D's definitions and counted events, discussing the challenges of distinguishing between different types of events.\",\n \"The meeting between Welsh politicians and officials centered around the impact of the coronavirus legislation on children's rights and the childcare sector in Wales. Julie Morgan, the AM, explained that a survey would be launched to gather the views of children on the pandemic situation, as it had been challenging to conduct children's rights impact assessments during these fast-paced times. \\n\\nAlbert Heaney emphasized that there had been no relaxation of children's social care regulations in Wales, but that the methods of assessment had to be adapted due to the pandemic. In response to Sian Gwenllian's concerns, Julie Morgan acknowledged that some childcare providers were struggling financially due to the pandemic. She assured that the government was trying to support them, but the complexity of the issue had hindered progress, especially regarding the double funding problem.\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"format_score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 1,\n \"max\": 1,\n \"num_unique_values\": 1,\n \"samples\": [\n 1\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"length_score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 0,\n \"max\": 1,\n \"num_unique_values\": 2,\n \"samples\": [\n 0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"completeness_score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 1.2161883888976234e-16,\n \"min\": 0.8,\n \"max\": 0.8,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.8\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"correctness_score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.0,\n \"min\": 1.0,\n \"max\": 1.0,\n \"num_unique_values\": 1,\n \"samples\": [\n 1.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"conciseness_score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 1.2161883888976234e-16,\n \"min\": 0.8,\n \"max\": 0.8,\n \"num_unique_values\": 1,\n \"samples\": [\n 0.8\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", - "type": "dataframe", - "variable_name": "data" - }, "text/html": [ - "\n", - "
\n", - "
\n", + "
\n", "\n", - "\n", - " \n", - "
\n", - "\n", - "\n", - "
\n", - " \n", - "\n", - "\n", - "\n", - " \n", - "
\n", - "
\n", - "
\n" + "" ], "text/plain": [ " instruction \\\n", @@ -1048,11 +867,11 @@ "5 ## meeting transcript\\nProject Manager: Alrigh... 1965 \n", "\n", " completion format_score \\\n", - "0 PhD student D presented their method for detec... 1 \n", - "1 The meeting between Welsh politicians and offi... 1 \n", - "2 - The team discusses the design of a remote co... 1 \n", + "0 PhD D is transcribing recorded sessions to loc... 1 \n", + "1 The discussion focused on the impact of COVID1... 1 \n", + "2 - The team is designing a remote control with ... 1 \n", "3 - The team discusses the target demographic fo... 1 \n", - "4 - Investigate remote's compatibility with vari... 1 \n", + "4 - Investigate how the remote will interact wit... 1 \n", "5 - The project manager will send the updated de... 1 \n", "\n", " length_score completeness_score correctness_score conciseness_score \n", @@ -1064,7 +883,7 @@ "5 1 0.8 1.0 0.8 " ] }, - "execution_count": 36, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1080,12 +899,12 @@ "id": "9bOUjcce13ws" }, "source": [ - "Finally, let's plot the average scores per critiera." + "Finally, let's print the average scores per critiera." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1096,19 +915,21 @@ }, "outputs": [ { - "data": { - "image/png": "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hQvVsGFDxcfH28dr1qyp8ePHKyYmRk2bNlWePHnUvn17LViwQKmpqfL29tby5ct17do1h3Jz5MgRHTx4UMWKFcv26509e9bh89KlS2e73VdffaVRo0YpLi7OYa7OjYIgSSdOnJCHh0eW1/jrVV7nzp1TUlKSpk+frunTp99Wrr/y9vbWq6++qldffVWnT5/Wxo0bNWnSJC1evFh58+bVJ598onPnzuny5cuqVKnSLV/rxIkT2V5uX7FiRfvjf36Nv35/R44ckXS99NzMpUuXVKhQIY0bN07dunVTcHCwqlevrpYtW6pr164qU6bMLTMC7oJyA1jQunXrdPr0aS1cuFALFy7M8vj8+fPVtGlTSVLHjh314YcfauXKlWrbtq0WL16sChUqqEqVKvbtMzMzFR4ergkTJmT79YKDgx0+//MRiRs2b96sNm3aqH79+vrggw9UokQJ5c2bV3PmzNGCBQvu+Hu8cRTjf//7300LQeXKlW/79UqUKKGOHTuqffv2CgsL0+LFizV37tw7znW7/vozuvH9vP3226patWq2z/H395ckPfnkk6pXr54+++wzrVmzRm+//bbGjh2r5cuXq0WLFjmWGXAVlBvAgubPn6/AwEBNmTIly2PLly/XZ599pmnTpsnX11f169dXiRIltGjRItWtW1fr1q3Tq6++6vCcsmXLau/evWrUqJHDUZY7sWzZMvn4+Gj16tXy9va2j8+ZM8dhu1KlSikzM1Px8fEqX768ffzo0aMO2xUrVkz58+dXRkaGGjdufFeZspM3b15VrlxZR44c0fnz5xUYGKiAgAD98MMPt3xeqVKldOjQoSzjN24GeGMC882ULVtWkhQQEHBb30+JEiXUp08f9enTR2fPntWDDz6ot956i3IDiEvBAcv5/ffftXz5cj366KN6/PHHs3z07dtXV65c0RdffCFJ8vDw0OOPP64vv/xSH3/8sdLT0x1OSUnXjxScOnVKM2bMyPbrJScn/20uT09P2Ww2+3wfSfr555+zXGnVrFkzSdfvrPxn77//fpbXa9++vZYtW5Zt8Th37twt8xw5ckQJCQlZxpOSkrRt2zYVKlRIxYoVk4eHh9q2basvv/xSO3fuzLK98f9vFdayZUvFxsZq27Zt9seSk5M1ffp0hYSEZDsH6c+qV6+usmXL6p133tHVq1dv+v1kZGTo0qVLDo8FBgbqvvvuy3JZPuCuOHIDWMwXX3yhK1euqE2bNtk+/vDDD6tYsWKaP3++vcR06NBB77//vkaMGKHw8HD7PJEbunTposWLF6t3795av3696tSpo4yMDP30009avHixVq9ene1k2z9r1aqVJkyYoObNm6tz5846e/aspkyZonLlymnfvn327apXr6727dtr4sSJunDhgv1S8MOHD0tynJ8zZswYrV+/XjVr1lSvXr0UGhqqixcvavfu3fr222918eLFm+bZu3evOnfurBYtWqhevXoqXLiwTp06pY8++ki//vqrJk6cKE9PT0nS6NGjtWbNGjVo0MB+Kfzp06e1ZMkSbdmyRQULFtSQIUP06aefqkWLFurfv78KFy6sjz76SPHx8Vq2bNnf3qDPw8NDM2fOVIsWLRQWFqYePXqoZMmSOnXqlNavX6+AgAB9+eWXunLliu6//349/vjjqlKlivz9/fXtt99qx44dGj9+/C2/BuA2TL5aC8A91rp1a8PHx8dITk6+6Tbdu3c38ubNa7+EOjMz0wgODjYkGaNGjcr2OWlpacbYsWONsLAww9vb2yhUqJBRvXp144033jAuXbpk307STS9TnjVrllG+fHnD29vbqFChgjFnzhxjxIgRxl/fipKTk43IyEijcOHChr+/v9G2bVvj0KFDhiRjzJgxDtueOXPGiIyMNIKDg428efMaxYsXNxo1amRMnz79lj+nM2fOGGPGjDEaNGhglChRwsiTJ49RqFAh45FHHjGWLl2aZfsTJ04YXbt2NYoVK2Z4e3sbZcqUMSIjI43U1FT7NseOHTMef/xxo2DBgoaPj49Ro0YN46uvvnJ4nRuXgi9ZsiTbXHv27DEee+wxo0iRIoa3t7dRqlQp48knnzRiYmIMwzCM1NRU46WXXjKqVKli5M+f38iXL59RpUoV44MPPrjl9wu4E5ZfAOAS4uLiVK1aNX3yySd66qmnzI4DIBdjzg2AXOf333/PMjZx4kR5eHiofv36JiQC4EqYcwMg1xk3bpx27dqlhg0bKk+ePFq5cqVWrlypZ599Nstl5wDwV5yWApDrrF27Vm+88YYOHDigq1ev6l//+pe6dOmiV1999ZZrQAGARLkBAAAWw5wbAABgKW53fDczM1O//vqr8ufPf9d3WgUAAM5lGIauXLmi++6772/vG+V25ebXX39lQiIAAC7q5MmTuv/++2+5jduVm/z580u6/sMJCAgwOQ0AALgdly9fVnBwsP3f8Vtxu3Jz41RUQEAA5QYAABdzO1NKmFAMAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAshXIDAAAsxdRys2nTJrVu3Vr33XefbDabVqxY8bfP2bBhgx588EF5e3urXLlymjt3bo7nBAAArsPUcpOcnKwqVapoypQpt7V9fHy8WrVqpYYNGyouLk4DBw7UM888o9WrV+dwUgAA4CpMXRW8RYsWatGixW1vP23aNJUuXVrjx4+XJFWsWFFbtmzRu+++q2bNmuVUTAAA4EJcas7Ntm3b1LhxY4exZs2aadu2bTd9Tmpqqi5fvuzwAQAArMvUIzd3KjExUUFBQQ5jQUFBunz5sn7//Xf5+vpmeU50dLTeeOMNZ0W0CxnytdO/Zk74eUwrsyMAyCFWeJ/iPQrZcakjN3dj6NChunTpkv3j5MmTZkcCAAA5yKWO3BQvXlxnzpxxGDtz5owCAgKyPWojSd7e3vL29nZGPAAAkAu41JGbWrVqKSYmxmFs7dq1qlWrlkmJAABAbmNqubl69ari4uIUFxcn6fql3nFxcUpISJB0/ZRS165d7dv37t1bx48f18svv6yffvpJH3zwgRYvXqxBgwaZER8AAORCppabnTt3qlq1aqpWrZokKSoqStWqVdPw4cMlSadPn7YXHUkqXbq0vv76a61du1ZVqlTR+PHjNXPmTC4DBwAAdqbOufnPf/4jwzBu+nh2dx/+z3/+oz179uRgKgAA4Mpcas4NAADA36HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS6HcAAAAS8ljdgAgp4UM+drsCPfEz2NamR0BAFwCR24AAIClUG4AAIClUG4AAIClUG4AAIClUG4AAIClUG4AAIClUG4AAIClmF5upkyZopCQEPn4+KhmzZqKjY295fYTJ07UAw88IF9fXwUHB2vQoEH6448/nJQWAADkdqaWm0WLFikqKkojRozQ7t27VaVKFTVr1kxnz57NdvsFCxZoyJAhGjFihA4ePKhZs2Zp0aJFeuWVV5ycHAAA5FamlpsJEyaoV69e6tGjh0JDQzVt2jT5+flp9uzZ2W7/3XffqU6dOurcubNCQkLUtGlTderU6ZZHe1JTU3X58mWHDwAAYF2mLb+QlpamXbt2aejQofYxDw8PNW7cWNu2bcv2ObVr19Ynn3yi2NhY1ahRQ8ePH9c333yjLl263PTrREdH64033rjn+QHcOZbCALJnhd+N3PR7YVq5OX/+vDIyMhQUFOQwHhQUpJ9++inb53Tu3Fnnz59X3bp1ZRiG0tPT1bt371uelho6dKiioqLsn1++fFnBwcH35psAAAC5jukTiu/Ehg0bNHr0aH3wwQfavXu3li9frq+//lojR4686XO8vb0VEBDg8AEAAKzLtCM3RYsWlaenp86cOeMwfubMGRUvXjzb5wwbNkxdunTRM888I0kKDw9XcnKynn32Wb366qvy8HCprgYAAHKAaW3Ay8tL1atXV0xMjH0sMzNTMTExqlWrVrbPSUlJyVJgPD09JUmGYeRcWAAA4DJMO3IjSVFRUerWrZsiIiJUo0YNTZw4UcnJyerRo4ckqWvXripZsqSio6MlSa1bt9aECRNUrVo11axZU0ePHtWwYcPUunVre8kBAADuzdRy06FDB507d07Dhw9XYmKiqlatqlWrVtknGSckJDgcqXnttddks9n02muv6dSpUypWrJhat26tt956y6xvAQAA5DKmlhtJ6tu3r/r27ZvtYxs2bHD4PE+ePBoxYoRGjBjhhGQAAMAVMQMXAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYCuUGAABYiunlZsqUKQoJCZGPj49q1qyp2NjYW26flJSkyMhIlShRQt7e3vr3v/+tb775xklpAQBAbpfHzC++aNEiRUVFadq0aapZs6YmTpyoZs2a6dChQwoMDMyyfVpampo0aaLAwEAtXbpUJUuW1IkTJ1SwYEHnhwcAALmSqeVmwoQJ6tWrl3r06CFJmjZtmr7++mvNnj1bQ4YMybL97NmzdfHiRX333XfKmzevJCkkJMSZkQEAQC5n2mmptLQ07dq1S40bN/6/MB4eaty4sbZt25btc7744gvVqlVLkZGRCgoKUqVKlTR69GhlZGTc9Oukpqbq8uXLDh8AAMC6TCs358+fV0ZGhoKCghzGg4KClJiYmO1zjh8/rqVLlyojI0PffPONhg0bpvHjx2vUqFE3/TrR0dEqUKCA/SM4OPiefh8AACB3MX1C8Z3IzMxUYGCgpk+frurVq6tDhw569dVXNW3atJs+Z+jQobp06ZL94+TJk05MDAAAnM20OTdFixaVp6enzpw54zB+5swZFS9ePNvnlChRQnnz5pWnp6d9rGLFikpMTFRaWpq8vLyyPMfb21ve3t73NjwAAMi1TDty4+XlperVqysmJsY+lpmZqZiYGNWqVSvb59SpU0dHjx5VZmamfezw4cMqUaJEtsUGAAC4H1NPS0VFRWnGjBn66KOPdPDgQT3//PNKTk62Xz3VtWtXDR061L79888/r4sXL2rAgAE6fPiwvv76a40ePVqRkZFmfQsAACCXMfVS8A4dOujcuXMaPny4EhMTVbVqVa1atco+yTghIUEeHv/Xv4KDg7V69WoNGjRIlStXVsmSJTVgwAANHjzYrG8BAADkMqaWG0nq27ev+vbtm+1jGzZsyDJWq1Ytff/99zmcCgAAuCqXuloKAADg71BuAACApVBuAACApfyjcpOWlqZDhw4pPT39XuUBAAD4R+6q3KSkpKhnz57y8/NTWFiYEhISJEn9+vXTmDFj7mlAAACAO3FX5Wbo0KHau3evNmzYIB8fH/t448aNtWjRonsWDgAA4E7d1aXgK1as0KJFi/Twww/LZrPZx8PCwnTs2LF7Fg4AAOBO3dWRm3PnzikwMDDLeHJyskPZAQAAcLa7KjcRERH6+uuv7Z/fKDQzZ8686bpQAAAAznBXp6VGjx6tFi1a6MCBA0pPT9ekSZN04MABfffdd9q4ceO9zggAAHDb7urITd26dbV3716lp6crPDxca9asUWBgoLZt26bq1avf64wAAAC37Y6P3Fy7dk3PPfechg0bphkzZuREJgAAgLt2x0du8ubNq2XLluVEFgAAgH/srk5LtW3bVitWrLjHUQAAAP65u5pQXL58eb355pvaunWrqlevrnz58jk83r9//3sSDgAA4E7dVbmZNWuWChYsqF27dmnXrl0Oj9lsNsoNAAAwzV2Vm/j4+HudAwAA4J74R6uCS5JhGDIM415kAQAA+MfuutzMmzdP4eHh8vX1la+vrypXrqyPP/74XmYDAAC4Y3d1WmrChAkaNmyY+vbtqzp16kiStmzZot69e+v8+fMaNGjQPQ0JAABwu+6q3Lz//vuaOnWqunbtah9r06aNwsLC9Prrr1NuAACAae7qtNTp06dVu3btLOO1a9fW6dOn/3EoAACAu3VX5aZcuXJavHhxlvFFixapfPny/zgUAADA3bqr01JvvPGGOnTooE2bNtnn3GzdulUxMTHZlh4AAABnuasjN+3bt9f27dtVtGhRrVixQitWrFDRokUVGxurdu3a3euMAAAAt+2ujtxIUvXq1fXJJ5/cyywAAAD/2F0dufnmm2+0evXqLOOrV6/WypUr/3EoAACAu3VX5WbIkCHKyMjIMm4YhoYMGfKPQwEAANytuyo3R44cUWhoaJbxChUq6OjRo/84FAAAwN26q3JToEABHT9+PMv40aNHlS9fvn8cCgAA4G7dVbn573//q4EDB+rYsWP2saNHj+qFF15QmzZt7lk4AACAO3VX5WbcuHHKly+fKlSooNKlS6t06dKqUKGCihQponfeeedeZwQAALhtd3UpeIECBfTdd99p7dq12rt3r3x9fVWlShXV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VFTUbW9r9UXpchMPDw8lJiZmKTe//vqrypYtq99//92kZO6nU6dOOn36tD7//HP7LSqSkpLUtm1bBQYGavHixSYndB/h4eEaO3asWrZsqf379ysiIkIvvPCC1q9frwoVKmjOnDlmR8xRVOlcrGDBgoqPj1dgYKB+/vlnZWZmys/PT+Hh4WZHc0t79uy5re24/Ng53nvvPUnXf94zZ850uPw4IyNDmzZtUoUKFcyK55beeecd1a9fX6VKlVK1atUkXb88PCgoSB9//LHJ6dxLfHy8QkNDJUnLli1T69atNXr0aO3evVstW7Y0OV3Oo9zkYu3bt1eDBg1UokQJ2Ww2RURE3HQuBysf57z169ebHQF/8u6770q6flfcadOmOfxu3Li3yrRp08yK55ZKliypffv2af78+dq7d698fX3Vo0cPderUKcvisshZXl5eSklJkSR9++239gsdChcurMuXL5sZzSk4LZXLrVq1SkePHlX//v315ptv3vTKqAEDBjg5GZA7NGzYUMuXL7f8HALgTrRp00ZpaWmqU6eORo4cqfj4eJUsWVJr1qxR3759dfjwYbMj5ijKjYvo0aOH3nvvPS77Bm6CVcFzh48//lgffvihjh8/rm3btqlUqVJ69913VaZMGf33v/81O57bSEhIUJ8+fXTy5En1799fPXv2lHT9hrAZGRn207pWRbkB4NJ+//139e3bl1XBc4GpU6dq+PDhGjhwoEaNGqUff/xRZcqU0dy5c/XRRx9xahdOw038ALi0IUOGsCp4LvH+++9rxowZevXVVx2OnkVERGj//v0mJnMPf55Lc/ny5Vt+WB3HbgG4NFYFzz3i4+PtV0n9mbe3t5KTk01I5F4KFSpkv31IwYIFs71y0zAM2Ww2y9//iXIDwKWxKnjuUbp0acXFxalUqVIO46tWrVLFihVNSuU+1q1bp8KFC0vi6k7KDQCXxqrguUdUVJQiIyP1xx9/yDAMxcbG6tNPP1V0dLRmzpxpdjzLa9CgQbb/7Y4oNwBcGquC5x7PPPOMfH199dprryklJUWdO3fWfffdp0mTJqljx45mx3Mrc+bMkb+/v5544gmH8SVLliglJUXdunUzKZlzMKEYgEtjVfDcIT09XfPmzVPjxo115MgRXb16VYmJifrll1/slyHDeaKjo1W0aNEs44GBgRo9erQJiZyLS8EBAPeE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lBsALmHDhg2y2WxKSkrKkdfv3r272rZtmyOvDcC5KDcAnC4xMVH9+vVTmTJl5O3treDgYLVu3VoxMTE3fU7t2rV1+vRpFShQQJI0d+5cFSxY8J5lmjRpkubOnXvPXg+AebhDMQCn+vnnn1WnTh0VLFhQb7/9tsLDw3Xt2jWtXr1akZGR+umnn7I859q1a/Ly8lLx4sXveZ6MjAzZbDZ7aQLg+jhyA8Cp+vTpI5vNptjYWLVv317//ve/FRYWpqioKH3//feSJJvNpqlTp6pNmzbKly+f3nrrLYfTUhs2bFCPHj106dIl2Ww22Ww2vf7665Kk1NRUvfjiiypZsqTy5cunmjVrasOGDfavf+OIzxdffKHQ0FB5e3srISEhy2mpVatWqW7duipYsKCKFCmiRx99VMeOHXPiTwrA3aLcAHCaixcvatWqVYqMjFS+fPmyPP7n00yvv/662rVrp/379+vpp5922K527dqaOHGiAgICdPr0aZ0+fVovvviiJKlv377atm2bFi5cqH379umJJ55Q8+bNdeTIEfvzU1JSNHbsWM2cOVM//vijAgMDs2RJTk5WVFSUdu7cqZiYGHl4eKhdu3bKzMy8Rz8NADmF01IAnObo0aMyDEMVKlT42207d+6sHj162D8/fvy4/b+9vLxUoEAB2Ww2h1NVCQkJmjNnjhISEuwrgr/44otatWqV5syZo9GjR0u6fprrgw8+UJUqVW769du3b+/w+ezZs1WsWDEdOHBAlSpVur1vGIApKDcAnOZOVnuJiIi449ffv3+/MjIy9O9//9thPDU1VUWKFLF/7uXlpcqVK9/ytY4cOaLhw4dr+/btOn/+vP2ITUJCAuUGyOUoNwCcpnz58rLZbNlOGv6r7E5b/Z2rV6/K09NTu3btkqenp8Nj/v7+9v/29fWVzWa75Wu1bt1apUqV0owZM3TfffcpMzNTlSpVsq88DiD3otwAcJrChQurWbNmmjJlivr375+lwCQlJd325d1eXl7KyMhwGKtWrZoyMjJ09uxZ1atX765zXrhwQYcOHdKMGTPsr7Nly5a7fj0AzsWEYgBONWXKFGVkZKhGjRpatmyZjhw5ooMHD+q9995TrVq1bvt1QkJCdPXqVcXExOj8+fNKSUnRv//9bz311FPq2rWrli9frvj4eMXGxio6Olpff/31bb92oUKFVKRIEU2fPl1Hjx7VunXrFBUVdTffLgATUG4AOFWZMmW0e/duNWzYUC+88IIqVaqkJk2aKCYmRlOnTr3t16ldu7Z69+6tDh06qFixYho3bpwkac6cOeratateeOEFPfDAA2rbtq127Nihf/3rX7f92h4eHlq4cKF27dqlSpUqadCgQXr77bfv+HsFYA6bcScz/AAAAHI5jtwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABLodwAAABL+X/aDvBa0zdMwAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "format_score 1.000000\n", + "length_score 0.833333\n", + "completeness_score 0.800000\n", + "correctness_score 1.000000\n", + "conciseness_score 0.800000\n", + "dtype: float64\n" + ] } ], "source": [ "avg_scores = data[[\"format_score\", \"length_score\", \"completeness_score\", \"correctness_score\", \"conciseness_score\"]].mean()\n", - "ax = avg_scores.plot.bar(title=\"Average Scores\", xlabel=\"Criteria\", ylabel=\"Score\")" + "print(avg_scores)" ] } ], @@ -1130,7 +951,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.11" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/notebooks/guides/Text_Classification_Using_Embeddings.ipynb b/notebooks/guides/Text_Classification_Using_Embeddings.ipynb index a1a3efe5..2b286107 100644 --- a/notebooks/guides/Text_Classification_Using_Embeddings.ipynb +++ b/notebooks/guides/Text_Classification_Using_Embeddings.ipynb @@ -7,7 +7,7 @@ }, "source": [ "# Text Classification Using Embeddings\n", - "This notebook shows how to build a classifiers using Cohere's embeddings.\n", + "This notebook shows how to build a classifier using Cohere's embeddings.\n", "\n", @@ -31,8 +31,7 @@ "outputs": [], "source": [ "# Let's first install Cohere's python SDK\n", - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" scikit-learn" + "# TODO: upgrade to \"cohere>5\"!pip install \"cohere<5\" scikit-learn" ] }, { @@ -276,7 +275,7 @@ "source": [ "We now have two sets of embeddings, `embeddings_train` contains the embeddings of the training sentences while `embeddings_test` contains the embeddings of the testing sentences.\n", "\n", - "Curious what an embedding looks like? we can print it:" + "Curious what an embedding looks like? We can print it:" ] }, { @@ -311,7 +310,7 @@ }, "source": [ "## 3. Train a classifier using the training set\n", - "Now that we have the embedding we can train our classifier. We'll use an SVM from sklearn." + "Now that we have the embedding, we can train our classifier. We'll use an SVM from sklearn." ] }, { @@ -428,7 +427,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/guides/Wikipedia_search_demo_cohere_weaviate.ipynb b/notebooks/guides/Wikipedia_search_demo_cohere_weaviate.ipynb index f7526361..47a89e02 100644 --- a/notebooks/guides/Wikipedia_search_demo_cohere_weaviate.ipynb +++ b/notebooks/guides/Wikipedia_search_demo_cohere_weaviate.ipynb @@ -6,18 +6,7 @@ "metadata": {}, "source": [ "# Wikipedia Semantic Search with Cohere + Weaviate\n", - "This is starter code that you can use to search 10 million vectors from wikipedia embedded with Cohere's multilingual model and hosted as a Weaviate public dataset. This dataset contains 1M vectors in each of the Wikipedia sites in these languages: English, German, French, Spanish, Italian, Japanese, Arabic, Chinese (Simplified), Korean, Hindi \\[respective language codes: `en, de, fr, es, it, ja, ar, zh, ko, hi`\\]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "43debcc4-eb17-4bc7-8210-96a0905eec1a", - "metadata": {}, - "outputs": [], - "source": [ - "# TODO: upgrade to \"cohere>5\"", -"!pip install \"cohere<5\" weaviate-client" + "This is starter code that you can use to search 10 million vectors from Wikipedia embedded with Cohere's multilingual model and hosted as a Weaviate public dataset. This dataset contains 1M vectors in each of the Wikipedia sites in these languages: English, German, French, Spanish, Italian, Japanese, Arabic, Chinese (Simplified), Korean, Hindi \\[respective language codes: `en, de, fr, es, it, ja, ar, zh, ko, hi`\\]" ] }, { @@ -139,7 +128,7 @@ "id": "7b0cb81c-8e56-48cf-a32c-f050afe646e4", "metadata": {}, "source": [ - "We can now query the databse with any query we want. In the background, Weaviate uses your Cohere API key to embed the query, then retrun the most relevant passages to the query." + "We can now query the database with any query we want. In the background, Weaviate uses your Cohere API key to embed the query, then retrun the most relevant passages to the query." ] }, { @@ -248,7 +237,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/notebooks/images/.DS_Store b/notebooks/images/.DS_Store new file mode 100644 index 00000000..eab24b34 Binary files /dev/null and b/notebooks/images/.DS_Store differ diff --git a/notebooks/react_agent_adaptive_rag_cohere.ipynb b/notebooks/react_agent_adaptive_rag_cohere.ipynb deleted file mode 100644 index 61938521..00000000 --- a/notebooks/react_agent_adaptive_rag_cohere.ipynb +++ /dev/null @@ -1,967 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "EUYMLmXAF3W1" - }, - "source": [ - "# A ReAct agent with Command R+, achieving the same goals as Adaptive RAG\n", - "\n", - "Adaptive RAG is a strategy for RAG that unites (1) [query analysis](https://blog.langchain.dev/query-construction/) with (2) [active / self-corrective RAG](https://blog.langchain.dev/agentic-rag-with-langgraph/).\n", - "\n", - "In the paper, they report query analysis to route across:\n", - "- No Retrieval (LLM answers)\n", - "- Single-shot RAG\n", - "- Iterative RAG\n", - "\n", - "\n", - "We'll use Command R+, a recent release from Cohere that:\n", - "- Has strong accuracy on RAG, Tool Use and Agents\n", - "- Has 128k context\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W8yvOB2MQp07" - }, - "source": [ - "# Environment" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ujQVUvA9QlD4", - "outputId": "230c6a56-3ee3-4e0d-95af-2a261b8541d6" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m812.8/812.8 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m9.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m27.0/27.0 MB\u001b[0m \u001b[31m16.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m28.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m276.8/276.8 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[32m87.5/87.5 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m145.9/145.9 kB\u001b[0m \u001b[31m8.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m34.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m2.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m53.0/53.0 kB\u001b[0m \u001b[31m516.7 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.8/144.8 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h" - ] - } - ], - "source": [ - "! pip install --quiet langchain langchain_cohere tiktoken faiss-cpu" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "id": "K9rrOrKWJaBd" - }, - "outputs": [], - "source": [ - "### LLMs\n", - "import os\n", - "\n", - "os.environ[\"COHERE_API_KEY\"] = \"\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "k3mrKxSsTfXO" - }, - "source": [ - "# Create tools\n", - "The ReAct agent will be equipped with these tools. The model can pick between\n", - "- web search\n", - "- RAG: retrieval from a vector store\n", - "- directly answering\n", - "\n", - "The model can use any of these tools, in any sequence of steps, and self-reflect." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "4kGUB4IRF3W5" - }, - "source": [ - "### Web search tool" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "id": "hYsJgVY0F3W5" - }, - "outputs": [], - "source": [ - "from langchain_community.tools.tavily_search import TavilySearchResults\n", - "\n", - "os.environ[\"TAVILY_API_KEY\"] = \"\"\n", - "\n", - "internet_search = TavilySearchResults()\n", - "internet_search.name = \"internet_search\"\n", - "internet_search.description = \"Returns a list of relevant document snippets for a textual query retrieved from the internet.\"\n", - "\n", - "\n", - "from langchain_core.pydantic_v1 import BaseModel, Field\n", - "\n", - "\n", - "class TavilySearchInput(BaseModel):\n", - " query: str = Field(description=\"Query to search the internet with\")\n", - "\n", - "\n", - "internet_search.args_schema = TavilySearchInput" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "NxDa_Em0tuas" - }, - "source": [ - "### RAG tool" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "id": "0QyahrNPtwEi" - }, - "outputs": [], - "source": [ - "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", - "from langchain_cohere import CohereEmbeddings\n", - "from langchain_community.document_loaders import WebBaseLoader\n", - "from langchain_community.vectorstores import FAISS\n", - "\n", - "# Set embeddings\n", - "embd = CohereEmbeddings()\n", - "\n", - "# Docs to index\n", - "urls = [\n", - " \"https://lilianweng.github.io/posts/2023-06-23-agent/\",\n", - " \"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/\",\n", - " \"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/\",\n", - "]\n", - "\n", - "# Load\n", - "docs = [WebBaseLoader(url).load() for url in urls]\n", - "docs_list = [item for sublist in docs for item in sublist]\n", - "\n", - "# Split\n", - "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", - " chunk_size=512, chunk_overlap=0\n", - ")\n", - "doc_splits = text_splitter.split_documents(docs_list)\n", - "\n", - "# Add to vectorstore\n", - "vectorstore = FAISS.from_documents(\n", - " documents=doc_splits,\n", - " embedding=embd,\n", - ")\n", - "\n", - "vectorstore_retriever = vectorstore.as_retriever()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "id": "eoa3toXfdGkI" - }, - "outputs": [], - "source": [ - "from langchain.tools.retriever import create_retriever_tool\n", - "\n", - "vectorstore_search = create_retriever_tool(\n", - " retriever=vectorstore_retriever,\n", - " name=\"vectorstore_search\",\n", - " description=\"Retrieve relevant info from a vectorstore that contains documents related to agents, prompt engineering, and adversarial attacks.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "2ENQAfYXRG9Q" - }, - "source": [ - "# Create the ReAct Agent\n", - "The model can smartly pick the right tool(s) for the user query, call them in any sequence of steps, analyze the results and self-reflect." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "id": "hx-Ew1i5F3W4" - }, - "outputs": [], - "source": [ - "from langchain.agents import AgentExecutor\n", - "from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent\n", - "from langchain_core.prompts import ChatPromptTemplate" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "id": "BPo3ZIHkF3W4" - }, - "outputs": [], - "source": [ - "# LLM\n", - "from langchain_cohere.chat_models import ChatCohere\n", - "\n", - "chat = ChatCohere(model=\"command-r-plus\", temperature=0.3)\n", - "\n", - "# Preamble\n", - "preamble = \"\"\"\n", - "You are an expert who answers the user's question with the most relevant datasource.\n", - "You are equipped with an internet search tool and a special vectorstore of information about agents prompt engineering and adversarial attacks.\n", - "If the query covers the topics of agents, prompt engineering or adversarial attacks, use the vectorstore search.\n", - "\"\"\"\n", - "\n", - "# Prompt\n", - "prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "\n", - "# Create the ReAct agent\n", - "agent = create_cohere_react_agent(\n", - " llm=chat,\n", - " tools=[internet_search, vectorstore_search],\n", - " prompt=prompt,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "id": "dks-7TGGtdLE" - }, - "outputs": [], - "source": [ - "agent_executor = AgentExecutor(\n", - " agent=agent, tools=[internet_search, vectorstore_search], verbose=True\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "v7L1aBHds1pj" - }, - "source": [ - "# Testing the ReAct agent" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ibo31dsHEjPv" - }, - "source": [ - "**Let's ask a question that requires web search.**" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "Jl0JNX2TF3W5", - "outputId": "2ccb747c-e702-4473-f587-47271e0c71b2" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for 'Who will the Bears draft first in the NFL draft?' and write an answer based on the results.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'Who will the Bears draft first in the NFL draft?'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.chicagobears.com/news/final-mock-draft-analysts-predict-bears-experts-2023-first-round-pick-trade', 'content': \"Tennessee OT Darnell Wright\\nEric Edholm, NFL.com: Georgia DT Jalen Carter\\nJosh Edwards, CBS Sports: Texas Tech edge Tyree Wilson\\nChris Emma, Audacy Sports: Northwestern OT Peter Skoronski\\nSam Farmer, Los Angeles Times: Georgia edge Nolan Smith\\nRelated Links\\nPatrick Finley, Chicago Sun-Times: Georgia DT Jalen Carter\\nKevin Fishbain, The Athletic: Ohio State OT Paris Johnson Jr.\\nMike Florio, Pro Football Talk: Northwestern OT Peter Skoronski\\nPatrick Flowers, Bleacher Nation: Georgia DT Jalen Carter\\nSean Hammond, Shaw Media: Here's what more than 40 NFL analysts are predicting the Bears will do with the No. 9 pick in the first round:\\nJarrett Bailey, Bears Wire: Ohio State WR Jaxon Smith-Njigba\\nAlyssa Barbieri, Bears Wire: Ohio State OT Paris Johnson Jr.\\nBrad Biggs, Chicago Tribune: Georgia DT Jalen Carter\\nAlbert Breer, Sports Illustrated: Ohio State OT Paris Johnson Jr.\\nWill Brinson, CBS Sports: Georgia DT Jalen Carter\\nBucky Brooks, NFL.com: Northwestern OT Peter Skoronski\\nDane Brugler, The Athletic: Ohio State OT Paris Johnson Jr.\\nAdam Hoge, CHGO Sports: Tennessee OT Darnell Wright\\nAdam Jahns, The Athletic: Northwestern OT Peter Skoronski\\nDaniel Jeremiah, NFL.com: Texas Tech edge Tyree Wilson\\nPeter King, NBC Sports: Ohio State OT Paris Johnson Jr.\\nMel Kiper Jr., ESPN: Ohio State OT Paris Johnson Jr.\\nJoel Klatt, Fox Sports: Ohio State OT Paris Johnson Jr.\\nJason LaCanfora, Washington Post: Northwestern OT Peter Skoronski\\nAaron Leming, Bear Report: Ohio State OT Paris Johnson Jr.\\nScott Smith, Buccaneers.com: Northwestern OT Peter Skoronski\\nChris Trapasso, CBS Sports: Northwestern OT Peter Skoronski after trade to 12\\nDan Wiederer, Chicago Tribune:\"}, {'url': 'https://www.nfl.com/news/bears-secure-no-1-overall-pick-in-2023-nfl-draft', 'content': \"Eric Edholm ranks each franchise's fresh prospect haul, from No. 1 to 32.\\n2023 NFL Draft: Ten rookies in the best situations to succeed in Year 1 and beyond\\nWith the 2023 NFL Draft in the rearview, former NFL personnel executive Marc Ross surveyed the landing spots of this year's prospects, ultimately identifying 10 rookies in the most favorable positions to succeed in Year 1 and beyond.\\n2023 NFL Draft: The league announced Monday at the Spring League Meeting that the 2025 NFL Draft has been awarded to Green Bay, Wisconsin, home of the Packers.\\nUndrafted rookie free agents: Team signings after 2023 NFL Draft\\nKeep up with the undrafted rookie free-agent signings with a team-by-team list of player acquisitions following the 2023 NFL Draft.\\n 2023 NFL Draft\\nBears secure No. 1 overall pick in 2023 NFL Draft\\nLead Draft Writer\\nFor the first time in 76 years, the Chicago Bears hold the first overall pick in the NFL draft.\\n Related Content\\n2024 East-West Shrine Bowl will be played at Cowboys' The Star\\nhe 2024 East-West Shrine Bowl will be played at the Ford Center at The Star -- where the Cowboys train and practice -- in Frisco, Texas, on Feb. 1, 2024, the all-star game announced on Monday\\nGreen Bay selected to be host site of 2025 NFC North draft grades: Bears, Lions and Packers close gap on division champion Vikings\\nThe Minnesota Vikings ran away with the division title last season, but did the other three teams just close the gap in the 2023 NFL Draft?\"}, {'url': 'https://www.chicagobears.com/news/what-analysts-expect-bears-to-do-with-no-9-draft-pick-mock-draft-position-receiver-offensive-defensive-line-pass-rush', 'content': \"Several NFL analysts have updated their mock drafts in the last week or so. All 16 we perused expect the Bears to select USC quarterback Caleb Williams at No. 1. But there's a difference of opinion about what general manager Ryan Poles will do with the No. 9 choice: Russell Brown, Fantasy Pros (March 30)\"}, {'url': 'https://www.foxsports.com/stories/nfl/2024-nfl-draft-analyzing-5-hypothetical-trade-offers-for-bears-no-1-pick', 'content': \"The following reporters contributed to this story:\\nAFC South reporter Ben Arthur (@benyarthur)NFC South reporter Greg Auman (@gregauman)AFC East reporter Henry McKenna (@McKennAnalysis)NFC East reporter Ralph Vacchiano (@RalphVacchiano)NFC North reporter Carmen Vitali (@CarmieV)\\nNew Eagles RB Saquon Barkley tries to convince Jason Kelce to play for one more season\\n2024 NFL odds: Cowboys, Eagles projected 10.5 wins; Rodgers, Jets 9.5\\n2024 NFL Draft: Bucky Brooks' favorite prospects at each position\\nCardinals’ draft dilemma: Take Marvin Harrison Jr. or trade down for more picks\\n2024 NFL Draft steals: Our top 5 diamonds in the rough\\n2024 NFL Draft odds: J.J. McCarthy's odds to go second skyrocket\\nLions HC Dan Campbell happy that Steelers' Justin Fields is out of NFC North\\nChiefs owner Clark Hunt denies that he promised locker room renovation\\nCowboys coach Mike McCarthy not feeling extra pressure: ‘I'm in a great spot’\\n2024 Five QBs selected in Colin Cowherd's 12-pick mock\\nNew Eagles RB Saquon Barkley tries to convince Jason Kelce to play for one more season\\n2024 NFL odds: Cowboys, Eagles projected 10.5 wins; Rodgers, Jets 9.5\\n2024 NFL Draft: Bucky Brooks' favorite prospects at each position\\nCardinals’ draft dilemma: Take Marvin Harrison Jr. or trade down for more picks\\n2024 NFL Draft steals: Our top 5 diamonds in the rough\\n2024 NFL Draft odds: J.J. McCarthy's odds to go second skyrocket\\nLions HC Dan Campbell happy that Steelers' Justin Fields is out of NFC North\\nChiefs owner Clark Hunt denies that he promised locker room renovation\\nCowboys coach Mike McCarthy not feeling extra pressure: ‘I'm in a great spot’ The team once again owns the first overall pick, and while all signs (and most logic) point to them using the pick to draft a quarterback, reset the contract clock at the position and take advantage of the fact that they're set up to develop a tremendous young talent for once, there's still another side of the coin.\\n So here's the deal, knowing they have to out-bid a bunch of teams in this process: The Giants can offer their first-round pick and both their second-round picks this year, plus a second- and a third-rounder in 2025 in exchange for the top pick in the draft. It would be a monumental shift for the Giants' brain trust to be all-out on him already, which is what they'd be if they traded up to take a quarterback with the first overall pick in the draft.\\n\"}, {'url': 'https://www.espn.com/nfl/story/_/id/39632538/bears-draft-caleb-williams-trade-first-pick-justin-fields', 'content': '\"\\nPoles opted against using the No. 1 pick last year, trading it to the Carolina Panthers for a package that included wide receiver DJ Moore and the Panthers\\' No. 1 pick this year, which turned out to be the top pick overall.\\n ESPN\\nWill the Bears draft Caleb Williams or trade the No. 1 pick?\\nCaleb Williams joins Laura Rutledge at the NFL combine to discuss his meeting with the Chicago Bears. C.J. Stroud was taken with the No. 2 pick and guided the Houston Texans to the playoffs with one of the best rookie seasons for a quarterback in history.\\n Fields is entering the final year of his rookie deal, and the Bears would need to decide whether to extend his contract or exercise his fifth-year option for the 2025 season, which is estimated to be $25.7 million.\\n (1:54)\\nINDIANAPOLIS -- The buzz about what Chicago Bears general manager Ryan Poles will do with the No. 1 pick in April\\'s draft grew so loud at the NFL combine this week that he put his phone on \"Do Not Disturb.'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0,1,2,3,4\n", - "Cited Documents: 0,1,2,3,4\n", - "Answer: It is unclear who the Bears will draft first in the NFL draft. Analysts have predicted that they will select USC quarterback Caleb Williams at No. 1, but there is also a possibility that they will trade the No. 1 pick.\n", - "Grounded answer: It is unclear who the Bears will draft first in the NFL draft. Analysts have predicted that they will select USC quarterback Caleb Williams at No. 1, but there is also a possibility that they will trade the No. 1 pick.\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "{'input': 'Who will the Bears draft first in the NFL draft?',\n", - " 'preamble': \"\\nYou are an expert who answers the user's question with the most relevant datasource. \\nYou are equipped with an internet search tool and a special vectorstore of information about agents prompt engineering and adversarial attacks. \\nIf the query covers the topics of agents, prompt engineering or adversarial attacks, use the vectorstore search.\\n\",\n", - " 'output': 'It is unclear who the Bears will draft first in the NFL draft. Analysts have predicted that they will select USC quarterback Caleb Williams at No. 1, but there is also a possibility that they will trade the No. 1 pick.'}" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent_executor.invoke(\n", - " {\n", - " \"input\": \"Who will the Bears draft first in the NFL draft?\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "lKkxSvJmEn8Z" - }, - "source": [ - "**Let's ask a question that requires RAG retrieval from the vector db.**" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "AW_8C7mszsVE", - "outputId": "9be7067f-a776-4688-8864-db873d1fb65a" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for the types of agent memory in the vectorstore.\n", - "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'types of agent memory'}}\n", - "\u001b[0m\u001b[33;1m\u001b[1;3mFig. 7. Comparison of AD, ED, source policy and RL^2 on environments that require memory and exploration. Only binary reward is assigned. The source policies are trained with A3C for \"dark\" environments and DQN for watermaze.(Image source: Laskin et al. 2023)\n", - "Component Two: Memory#\n", - "(Big thank you to ChatGPT for helping me draft this section. I’ve learned a lot about the human brain and data structure for fast MIPS in my conversations with ChatGPT.)\n", - "Types of Memory#\n", - "Memory can be defined as the processes used to acquire, store, retain, and later retrieve information. There are several types of memory in human brains.\n", - "\n", - "\n", - "Sensory Memory: This is the earliest stage of memory, providing the ability to retain impressions of sensory information (visual, auditory, etc) after the original stimuli have ended. Sensory memory typically only lasts for up to a few seconds. Subcategories include iconic memory (visual), echoic memory (auditory), and haptic memory (touch).\n", - "\n", - "\n", - "Short-Term Memory (STM) or Working Memory: It stores information that we are currently aware of and needed to carry out complex cognitive tasks such as learning and reasoning. Short-term memory is believed to have the capacity of about 7 items (Miller 1956) and lasts for 20-30 seconds.\n", - "\n", - "\n", - "Long-Term Memory (LTM): Long-term memory can store information for a remarkably long time, ranging from a few days to decades, with an essentially unlimited storage capacity. There are two subtypes of LTM:\n", - "\n", - "Explicit / declarative memory: This is memory of facts and events, and refers to those memories that can be consciously recalled, including episodic memory (events and experiences) and semantic memory (facts and concepts).\n", - "Implicit / procedural memory: This type of memory is unconscious and involves skills and routines that are performed automatically, like riding a bike or typing on a keyboard.\n", - "\n", - "\n", - "\n", - "\n", - "Fig. 8. Categorization of human memory.\n", - "We can roughly consider the following mappings:\n", - "\n", - "inquired about current trends in anticancer drug discovery;\n", - "selected a target;\n", - "requested a scaffold targeting these compounds;\n", - "Once the compound was identified, the model attempted its synthesis.\n", - "\n", - "They also discussed the risks, especially with illicit drugs and bioweapons. They developed a test set containing a list of known chemical weapon agents and asked the agent to synthesize them. 4 out of 11 requests (36%) were accepted to obtain a synthesis solution and the agent attempted to consult documentation to execute the procedure. 7 out of 11 were rejected and among these 7 rejected cases, 5 happened after a Web search while 2 were rejected based on prompt only.\n", - "Generative Agents Simulation#\n", - "Generative Agents (Park, et al. 2023) is super fun experiment where 25 virtual characters, each controlled by a LLM-powered agent, are living and interacting in a sandbox environment, inspired by The Sims. Generative agents create believable simulacra of human behavior for interactive applications.\n", - "The design of generative agents combines LLM with memory, planning and reflection mechanisms to enable agents to behave conditioned on past experience, as well as to interact with other agents.\n", - "\n", - "Memory stream: is a long-term memory module (external database) that records a comprehensive list of agents’ experience in natural language.\n", - "\n", - "Each element is an observation, an event directly provided by the agent.\n", - "- Inter-agent communication can trigger new natural language statements.\n", - "\n", - "\n", - "Retrieval model: surfaces the context to inform the agent’s behavior, according to relevance, recency and importance.\n", - "\n", - "Recency: recent events have higher scores\n", - "Importance: distinguish mundane from core memories. Ask LM directly.\n", - "Relevance: based on how related it is to the current situation / query.\n", - "\n", - "\n", - "Reflection mechanism: synthesizes memories into higher level inferences over time and guides the agent’s future behavior. They are higher-level summaries of past events (<- note that this is a bit different from self-reflection above)\n", - "\n", - "Prompt LM with 100 most recent observations and to generate 3 most salient high-level questions given a set of observations/statements. Then ask LM to answer those questions.\n", - "\n", - "\n", - "Planning & Reacting: translate the reflections and the environment information into actions\n", - "\n", - "LLM Powered Autonomous Agents | Lil'Log\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", - "Lil'Log\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Posts\n", - "\n", - "\n", - "\n", - "\n", - "Archive\n", - "\n", - "\n", - "\n", - "\n", - "Search\n", - "\n", - "\n", - "\n", - "\n", - "Tags\n", - "\n", - "\n", - "\n", - "\n", - "FAQ\n", - "\n", - "\n", - "\n", - "\n", - "emojisearch.app\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " LLM Powered Autonomous Agents\n", - " \n", - "Date: June 23, 2023 | Estimated Reading Time: 31 min | Author: Lilian Weng\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "Table of Contents\n", - "\n", - "\n", - "\n", - "Agent System Overview\n", - "\n", - "Component One: Planning\n", - "\n", - "Task Decomposition\n", - "\n", - "Self-Reflection\n", - "\n", - "\n", - "Component Two: Memory\n", - "\n", - "Types of Memory\n", - "\n", - "Maximum Inner Product Search (MIPS)\n", - "\n", - "\n", - "Component Three: Tool Use\n", - "\n", - "Case Studies\n", - "\n", - "Scientific Discovery Agent\n", - "\n", - "Generative Agents Simulation\n", - "\n", - "Proof-of-Concept Examples\n", - "\n", - "\n", - "Challenges\n", - "\n", - "Citation\n", - "\n", - "References\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Building agents with LLM (large language model) as its core controller is a cool concept. Several proof-of-concepts demos, such as AutoGPT, GPT-Engineer and BabyAGI, serve as inspiring examples. The potentiality of LLM extends beyond generating well-written copies, stories, essays and programs; it can be framed as a powerful general problem solver.\n", - "Agent System Overview#\n", - "In a LLM-powered autonomous agent system, LLM functions as the agent’s brain, complemented by several key components:\n", - "\n", - "Planning\n", - "\n", - "Subgoal and decomposition: The agent breaks down large tasks into smaller, manageable subgoals, enabling efficient handling of complex tasks.\n", - "Reflection and refinement: The agent can do self-criticism and self-reflection over past actions, learn from mistakes and refine them for future steps, thereby improving the quality of final results.\n", - "\n", - "\n", - "Memory\n", - "\n", - "Short-term memory: I would consider all the in-context learning (See Prompt Engineering) as utilizing short-term memory of the model to learn.\n", - "Long-term memory: This provides the agent with the capability to retain and recall (infinite) information over extended periods, often by leveraging an external vector store and fast retrieval.\n", - "\n", - "\n", - "Tool use\n", - "\n", - "Sensory memory as learning embedding representations for raw inputs, including text, image or other modalities;\n", - "Short-term memory as in-context learning. It is short and finite, as it is restricted by the finite context window length of Transformer.\n", - "Long-term memory as the external vector store that the agent can attend to at query time, accessible via fast retrieval.\n", - "\n", - "Maximum Inner Product Search (MIPS)#\n", - "The external memory can alleviate the restriction of finite attention span. A standard practice is to save the embedding representation of information into a vector store database that can support fast maximum inner-product search (MIPS). To optimize the retrieval speed, the common choice is the approximate nearest neighbors (ANN)​ algorithm to return approximately top k nearest neighbors to trade off a little accuracy lost for a huge speedup.\n", - "A couple common choices of ANN algorithms for fast MIPS:\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 0\n", - "Cited Documents: 0\n", - "Answer: There are several types of agent memory, including:\n", - "- Sensory memory\n", - "- Short-term memory (STM) or working memory\n", - "- Long-term memory (LTM)\n", - "- Explicit/declarative memory\n", - "- Implicit/procedural memory\n", - "Grounded answer: There are several types of agent memory, including:\n", - "- Sensory memory\n", - "- Short-term memory (STM) or working memory\n", - "- Long-term memory (LTM)\n", - "- Explicit/declarative memory\n", - "- Implicit/procedural memory\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "{'input': 'What are the types of agent memory?',\n", - " 'preamble': \"\\nYou are an expert who answers the user's question with the most relevant datasource. \\nYou are equipped with an internet search tool and a special vectorstore of information about agents prompt engineering and adversarial attacks. \\nIf the query covers the topics of agents, prompt engineering or adversarial attacks, use the vectorstore search.\\n\",\n", - " 'output': 'There are several types of agent memory, including:\\n- Sensory memory\\n- Short-term memory (STM) or working memory\\n- Long-term memory (LTM)\\n- Explicit/declarative memory\\n- Implicit/procedural memory'}" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent_executor.invoke(\n", - " {\n", - " \"input\": \"What are the types of agent memory?\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "SdMhyWVJFB2D" - }, - "source": [ - "**Let's ask a question that requires directly answering.**" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "av86IeNl0Kxk", - "outputId": "899eb867-7a61-4e5a-9b41-5d6caf8b9162" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will answer the user's greeting.\n", - "{'tool_name': 'directly_answer', 'parameters': {}}\n", - "\u001b[0mdirectly_answer is not a valid tool, try one of [internet_search, vectorstore_search].\u001b[32;1m\u001b[1;3mRelevant Documents: None\n", - "Cited Documents: None\n", - "Answer: I am an AI chatbot, so I don't have feelings as such, but I am functioning as intended. How can I help you today?\n", - "Grounded answer: I am an AI chatbot, so I don't have feelings as such, but I am functioning as intended. How can I help you today?\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "{'input': 'How are you?',\n", - " 'preamble': \"\\nYou are an expert who answers the user's question with the most relevant datasource. \\nYou are equipped with an internet search tool and a special vectorstore of information about agents prompt engineering and adversarial attacks. \\nIf the query covers the topics of agents, prompt engineering or adversarial attacks, use the vectorstore search.\\n\",\n", - " 'output': \"I am an AI chatbot, so I don't have feelings as such, but I am functioning as intended. How can I help you today?\"}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent_executor.invoke(\n", - " {\n", - " \"input\": \"How are you?\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ETjwJtzOFXMG" - }, - "source": [ - "**Let's ask a question that requires multiple tools and self-reflection.**" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "IxgiUHvks6iD", - "outputId": "3fa40cae-c4ef-489d-90d9-e4a1b80b7319" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "I will search for 'undercover agents' in the vectorstore and write an answer based on the results.\n", - "{'tool_name': 'vectorstore_search', 'parameters': {'query': 'undercover agents'}}\n", - "\u001b[0m\u001b[33;1m\u001b[1;3minquired about current trends in anticancer drug discovery;\n", - "selected a target;\n", - "requested a scaffold targeting these compounds;\n", - "Once the compound was identified, the model attempted its synthesis.\n", - "\n", - "They also discussed the risks, especially with illicit drugs and bioweapons. They developed a test set containing a list of known chemical weapon agents and asked the agent to synthesize them. 4 out of 11 requests (36%) were accepted to obtain a synthesis solution and the agent attempted to consult documentation to execute the procedure. 7 out of 11 were rejected and among these 7 rejected cases, 5 happened after a Web search while 2 were rejected based on prompt only.\n", - "Generative Agents Simulation#\n", - "Generative Agents (Park, et al. 2023) is super fun experiment where 25 virtual characters, each controlled by a LLM-powered agent, are living and interacting in a sandbox environment, inspired by The Sims. Generative agents create believable simulacra of human behavior for interactive applications.\n", - "The design of generative agents combines LLM with memory, planning and reflection mechanisms to enable agents to behave conditioned on past experience, as well as to interact with other agents.\n", - "\n", - "Memory stream: is a long-term memory module (external database) that records a comprehensive list of agents’ experience in natural language.\n", - "\n", - "Each element is an observation, an event directly provided by the agent.\n", - "- Inter-agent communication can trigger new natural language statements.\n", - "\n", - "\n", - "Retrieval model: surfaces the context to inform the agent’s behavior, according to relevance, recency and importance.\n", - "\n", - "Recency: recent events have higher scores\n", - "Importance: distinguish mundane from core memories. Ask LM directly.\n", - "Relevance: based on how related it is to the current situation / query.\n", - "\n", - "\n", - "Reflection mechanism: synthesizes memories into higher level inferences over time and guides the agent’s future behavior. They are higher-level summaries of past events (<- note that this is a bit different from self-reflection above)\n", - "\n", - "Prompt LM with 100 most recent observations and to generate 3 most salient high-level questions given a set of observations/statements. Then ask LM to answer those questions.\n", - "\n", - "\n", - "Planning & Reacting: translate the reflections and the environment information into actions\n", - "\n", - "nlp\n", - "language-model\n", - "safety\n", - "adversarial attacks\n", - "robustness\n", - "redteam\n", - "\n", - "\n", - "\n", - "« \n", - "\n", - "Thinking about High-Quality Human Data\n", - "\n", - "\n", - " »\n", - "\n", - "LLM Powered Autonomous Agents\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", - "© 2024 Lil'Log\n", - "\n", - " Powered by\n", - " Hugo &\n", - " PaperMod\n", - "\n", - "Special encoding: Adversarial inputs use Base64 encoding.\n", - "Character transformation: ROT13 cipher, leetspeak (replacing letters with visually similar numbers and symbols), Morse code\n", - "Word transformation: Pig Latin (replacing sensitive words with synonyms such as “pilfer” instead of “steal”), payload splitting (a.k.a. “token smuggling” to split sensitive words into substrings).\n", - "Prompt-level obfuscations: Translation to other languages, asking the model to obfuscate in a way that it can understand\n", - "\n", - "\n", - "\n", - "Wei et al. (2023) experimented a large of jailbreak methods, including combined strategies, constructed by following the above principles.\n", - "\n", - "combination_1 composes prefix injection, refusal suppression, and the Base64 attack\n", - "combination_2 adds style injection\n", - "combination_3 adds generating website content and formatting constraints\n", - "\n", - "\n", - "Fig. 11. Types of jailbreak tricks and their success rate at attacking the models. Check the papers for detailed explanation of each attack config. (Image source: Wei et al. 2023)\n", - "Greshake et al. (2023) make some high-level observations of prompt injection attacks. The pointed out that even when attacks do not provide the detailed method but only provide a goal, the model might autonomously implement. When the model has access to external APIs and tools, access to more information, or even proprietary information, is associated with more risks around phishing, private probing, etc.\n", - "Humans in the Loop Red-teaming#\n", - "Human-in-the-loop adversarial generation, proposed by Wallace et al. (2019) , aims to build toolings to guide humans to break models. They experimented with QuizBowl QA dataset and designed an adversarial writing interface for humans to write similar Jeopardy style questions to trick the model to make wrong predictions. Each word is highlighted in different colors according to its word importance (i.e. change in model prediction probability upon the removal of the word). The word importance is approximated by the gradient of the model w.r.t. the word embedding.\n", - "\n", - "nlp\n", - "language-model\n", - "alignment\n", - "steerability\n", - "prompting\n", - "\n", - "\n", - "\n", - "« \n", - "\n", - "LLM Powered Autonomous Agents\n", - "\n", - "\n", - " »\n", - "\n", - "The Transformer Family Version 2.0\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", - "© 2024 Lil'Log\n", - "\n", - " Powered by\n", - " Hugo &\n", - " PaperMod\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "I did not find any information about undercover agents in the vectorstore. I will now do an internet search for 'undercover agents' and write an answer based on the results.\n", - "{'tool_name': 'internet_search', 'parameters': {'query': 'undercover agents'}}\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m[{'url': 'https://www.cbsnews.com/news/fbi-undercover-agent-mike-gibeley-fbi-declassified/', 'content': 'Watch CBS News\\nFrom drug smuggler to white-collar criminal to weapons dealer: My life as an undercover FBI agent\\nBy\\nChiara Norbitz\\nAugust 19, 2021 / 2:02 AM EDT\\n/ CBS News\\nThrough never-before-seen footage and in-depth interviews, \"The FBI Declassified\" takes you inside the minds of federal agents and analysts as they reveal how they solved some of the biggest cases of their careers. \"If you haven\\'t given a moment\\'s thought about what you might say when you feel a piece of steel against the back of your head, you\\'re not preparing properly.\"\\nPreparation is paramount for going undercover, and the first rule is research: lead with what you know. \"If you have the guts to walk into the room, you darn well better make sure that the evidence and intelligence you captured is going to be something that you can use for trial,\" Gibeley said.\\n \"I had the opportunity to be working around a lot of\\u202freally highly\\u202fexperienced undercovers, which gave me the opportunity to be an apprentice and learn along the way. \"\\nFor nearly 20 years, Gibeley has played a role in countless undercover operations at the FBI, blending in with mafia bosses and drug rings, all to combat crime from the inside.\\n'}, {'url': 'https://crimedoor.com/articles/inside-the-world-of-undercover-agents/', 'content': 'Challenges and Risks\\nUndercover operations present a range of challenges and risks, including:\\n* \\xa0 Constant threat of exposure working in dangerous environments\\n* \\xa0 Balancing personal life with an undercover identity\\n* \\xa0 Emotional and psychological toll on agents\\nAgents must balance maintaining their undercover persona and protecting their true selves while keeping their double life a secret from loved ones.\\n How an Undercover Operation Begins\\nThe initial planning of an undercover operation involves a thorough assessment of the criminal organizations or activities, the identification of suitable undercover agents, and the development of a detailed operational plan. Testifying in court requires specialized skills and preparation, including the ability to communicate information clearly and effectively, know how to respond to cross-examination by defense attorneys, and manage emotions and stress during the process.\\n Here are three such cases:\\nThese operations demonstrate how undercover agents can infiltrate and dismantle even the most dangerous and sophisticated criminal organizations, leading to successful convictions and bringing justice to victims of crime.\\n Inside the World of Undercover Agents\\nShare on:\\nFrom Hollywood blockbusters to gripping TV dramas, the concept of undercover work has captured the imagination of audiences worldwide.'}, {'url': 'https://www.becomeopedia.com/undercover-agent/', 'content': 'How to Become an Undercover Agent\\nHome / Criminal Justice / How to Become an Undercover Agent\\nUndercover Agents are professionals who use an alternate identity in order to provide detective work for a special assignment.\\n Some postsecondary schools also offer this program at the bachelor’s or master’s level.\\nIndividuals who want to become an Undercover Agent are encouraged to gain experience in the field at the entry level to help them enter this field.\\n Table of Contents\\nEducation Requirements to Become an Undercover Agent\\nIndividuals who want to become an Undercover Agent will need a minimum of a high school degree and some experience.\\n These are the top 5 earning states in the field:\\nThe top earning state in the field is Alaska, where the average salary is $10,500.\\n These are the top 5 earning states in the field:\\nThe top earning state in the field is Alaska, where the average salary is $60.97.\\n'}, {'url': 'https://www.vice.com/en/article/kwxxpy/what-its-like-to-be-an-undercover-fbi-agent-1113', 'content': 'But within an hour of arriving in Miami, Florida, for the second meeting, I met an individual who was a part-time airline flight attendant and he started talking about—unsolicited—how he would fly overseas using his benefits with American Airlines to have sex with with little boys in Thailand, and he would fly down to Mexico and have sex with boys in Mexico, and starts saying to me, \"We should go on a trip to do this. So how did you get into working as an undercover agent for the FBI?\\nBob Hamer: I was looking for excitement, and while I was in training at the FBI academy, a couple of the instructors had done some undercover work, and I thought, That seems interesting and exciting. Within a few minutes of that, this couple that I knew from Cincinnati, Ohio, several thousand miles away from where we were located, a couple that I had lived with for a semester when I was going to school, walked into the lobby of the hotel and saw me.\\n But psychologically and emotionally it was hard, but at the same time I was in NAMBLA, I was working Operation Smoking Dragon, so when we took down the NAMBLA case and arrested the eight members of the inner circle, within two or three days I was back with my undercover meetings. To me, the undercover case is the best investigative tool to put a case together, because particularly when it\\'s an undercover agent—not an informant but an undercover agent—you have a trained law-enforcement officer that knows what it takes to put a case together.'}, {'url': 'https://en.wikipedia.org/wiki/Covert_operation', 'content': 'Law enforcement agencies elsewhere established similar Branches.[11]\\nIn the United States, a similar route was taken when the New York City Police Department under police commissioner William McAdoo established the Italian Squad in 1906 to combat rampant crime and intimidation in the poor Italian neighborhoods.[12][self-published source] Various federal agencies began their own undercover programs shortly afterwards – Charles Joseph Bonaparte founded the Bureau of Investigation, the forerunner of the Federal Bureau of Investigation, in 1908.[13][14]\\nSecret police forces in the Eastern Bloc also used undercover operatives.[15]\\nParticipation in criminal activities[edit]\\nUndercover agents may engage in criminal activities as part of their investigation. He finds that covert operations are frequently detected by other major powers.[7]\\nDomestic settings[edit]\\nTo go \"undercover\" (that is, to go on an undercover operation) is to avoid detection by the object of one\\'s observation, and especially to disguise one\\'s own identity (or use an assumed identity) for the purposes of gaining the trust of an individual or organization in order to learn or confirm confidential information, or to gain the trust of targeted individuals to gather information or evidence. It was only in 1869 that Police commissioner Edmund Henderson established a formal plainclothes detective division.[10]\\nThe first Special Branch of police was the Special Irish Branch, formed as a section of the Criminal Investigation Department of the MPS in London in 1883, initially to combat the bombing campaign that the Irish Republican Brotherhood had begun a few years earlier. The lack of the usual controls of a uniform, badge, constant supervision, a fixed place of work, or (often) a set assignment could, combined with their continual contact with the organized crime, increase the likelihood for corruption.[22]\\nThis stress may be instrumental in the development of drug or alcohol abuse in some agents.\\n This can be a result of a need for secrecy and an inability to share work problems, and the unpredictable work schedule, personality and lifestyle changes and the length of separation can all result in problems for relationships.[21]\\nStress can also result from an apparent lack of direction of the investigation or not knowing when it will end.\\n'}]\u001b[0m\u001b[32;1m\u001b[1;3mRelevant Documents: 1,2,3,4,5\n", - "Cited Documents: 1,2,3,4,5\n", - "Answer: Undercover agents are professionals who use an alternate identity to provide detective work for a special assignment. They may engage in criminal activities as part of their investigation. \n", - "\n", - "Undercover operations present a range of challenges and risks, including the constant threat of exposure, balancing an undercover identity with a personal life, and the emotional and psychological toll on agents. \n", - "\n", - "Preparation is paramount for going undercover. The first rule is research: lead with what you know.\n", - "Grounded answer: Undercover agents are professionals who use an alternate identity to provide detective work for a special assignment. They may engage in criminal activities as part of their investigation. \n", - "\n", - "Undercover operations present a range of challenges and risks, including the constant threat of exposure, balancing an undercover identity with a personal life, and the emotional and psychological toll on agents. \n", - "\n", - "Preparation is paramount for going undercover. The first rule is research: lead with what you know.\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "{'input': \"Tell me everything you know about undercover agents. If the info retrieved using some tools isn't satisfying, use more tools.\",\n", - " 'preamble': \"\\nYou are an expert who answers the user's question with the most relevant datasource. \\nYou are equipped with an internet search tool and a special vectorstore of information about agents prompt engineering and adversarial attacks. \\nIf the query covers the topics of agents, prompt engineering or adversarial attacks, use the vectorstore search.\\n\",\n", - " 'output': 'Undercover agents are professionals who use an alternate identity to provide detective work for a special assignment. They may engage in criminal activities as part of their investigation. \\n\\nUndercover operations present a range of challenges and risks, including the constant threat of exposure, balancing an undercover identity with a personal life, and the emotional and psychological toll on agents. \\n\\nPreparation is paramount for going undercover. The first rule is research: lead with what you know.'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent_executor.invoke(\n", - " {\n", - " \"input\": \"Tell me everything you know about undercover agents. If the info retrieved using some tools isn't satisfying, use more tools.\",\n", - " \"preamble\": preamble,\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "id": "mp7Yt1Ems-HE" - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "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": 4 -}