diff --git a/docs/langchain-retrieval-augmentation.ipynb b/docs/langchain-retrieval-augmentation.ipynb index f9ce1a22..3b5317ad 100644 --- a/docs/langchain-retrieval-augmentation.ipynb +++ b/docs/langchain-retrieval-augmentation.ipynb @@ -1,875 +1,1267 @@ { - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "f0Qrii3fJYbS" - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/langchain-retrieval-augmentation.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/docs/langchain-retrieval-augmentation.ipynb)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "dQRA1HWOJYbU" - }, - "source": [ - "#### [LangChain Handbook](https://pinecone.io/learn/langchain)\n", - "\n", - "# Retrieval Augmentation\n", - "\n", - "**L**arge **L**anguage **M**odels (LLMs) have a data freshness problem. The most powerful LLMs in the world, like GPT-4, have no idea about recent world events.\n", - "\n", - "The world of LLMs is frozen in time. Their world exists as a static snapshot of the world as it was within their training data.\n", - "\n", - "A solution to this problem is *retrieval augmentation*. The idea behind this is that we retrieve relevant information from an external knowledge base and give that information to our LLM. In this notebook we will learn how to do that.\n", - "\n", - "[![Open full notebook](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/full-link.svg)](https://github.com/pinecone-io/examples/blob/master/learn/generation/langchain/handbook/05-langchain-retrieval-augmentation.ipynb)\n", - "\n", - "To begin, we must install the prerequisite libraries that we will be using in this notebook." - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": { - "id": "0_4wHAWtmAvJ" - }, - "outputs": [], - "source": [ - "!pip install -qU \\\n", - " pinecone==5.4.2 \\\n", - " pinecone-datasets==1.0.2 \\\n", - " pinecone-notebooks==0.1.1 \\\n", - " langchain==0.3.20 \\\n", - " langchain-openai==0.3.9 \\\n", - " langchain-pinecone==0.2.3 \\\n", - " tqdm" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "\n", - "\ud83d\udea8 _Note: the above `pip install` is formatted for Jupyter notebooks. If running elsewhere you may need to drop the `!`._\n", - "\n", - "---" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "RaVQA7J0JYbV" - }, - "source": [ - "## Building the Knowledge Base\n", - "\n", - "We will download a pre-embedding dataset from `pinecone-datasets`. Allowing us to skip the embedding and preprocessing steps, if you'd rather work through those steps you can find the [full notebook here](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/langchain-retrieval-augmentation.ipynb).\n", - "\n", - "The dataset we will be working with in this demo contains 50K chunked wikipedia articles that have been embedded using OpenAI's `text-embedding-ada-002` embedding model. This model produces embeddings with a dimension of 1536." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 262 - }, - "id": "LeAmSrjvKJrV", - "outputId": "2ec76d28-1f4b-4db4-a919-98ffa01fb8a0" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Loading documents parquet files: 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 5/5 [01:21<00:00, 16.22s/it]\n" - ] - }, - { - "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", - "
idvaluesmetadata
01-0[-0.011254455894231796, -0.01698738895356655, ...{'chunk': 0, 'source': 'https://simple.wikiped...
11-1[-0.0015197008615359664, -0.007858820259571075...{'chunk': 1, 'source': 'https://simple.wikiped...
21-2[-0.009930099360644817, -0.012211072258651257,...{'chunk': 2, 'source': 'https://simple.wikiped...
31-3[-0.011600767262279987, -0.012608098797500134,...{'chunk': 3, 'source': 'https://simple.wikiped...
41-4[-0.026462381705641747, -0.016362832859158516,...{'chunk': 4, 'source': 'https://simple.wikiped...
\n", - "
" - ], - "text/plain": [ - " id values \\\n", - "0 1-0 [-0.011254455894231796, -0.01698738895356655, ... \n", - "1 1-1 [-0.0015197008615359664, -0.007858820259571075... \n", - "2 1-2 [-0.009930099360644817, -0.012211072258651257,... \n", - "3 1-3 [-0.011600767262279987, -0.012608098797500134,... \n", - "4 1-4 [-0.026462381705641747, -0.016362832859158516,... \n", - "\n", - " metadata \n", - "0 {'chunk': 0, 'source': 'https://simple.wikiped... \n", - "1 {'chunk': 1, 'source': 'https://simple.wikiped... \n", - "2 {'chunk': 2, 'source': 'https://simple.wikiped... \n", - "3 {'chunk': 3, 'source': 'https://simple.wikiped... \n", - "4 {'chunk': 4, 'source': 'https://simple.wikiped... " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pinecone_datasets import load_dataset\n", - "\n", - "dataset = load_dataset('wikipedia-simple-text-embedding-ada-002-50K')\n", - "\n", - "# We drop sparse_values and blob keys as they are not needed for this example\n", - "dataset.documents.drop(['sparse_values'], axis=1, inplace=True)\n", - "dataset.documents.drop(['blob'], axis=1, inplace=True)\n", - "\n", - "dataset.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "QPUmWYSA43eC" - }, - "source": [ - "Now we move on to initializing our Pinecone vector database." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Initializing the Pinecone client\n", - "\n", - "Now the data is ready, we need to set up an index to store it.\n", - "\n", - "We begin by initializing our connection to Pinecone. To do this we need a [free API key](https://app.pinecone.io)." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "if not os.environ.get(\"PINECONE_API_KEY\"):\n", - " from pinecone_notebooks.colab import Authenticate\n", - " Authenticate()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/conda/lib/python3.12/site-packages/pinecone/data/index.py:1: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from tqdm.autonotebook import tqdm\n" - ] - } - ], - "source": [ - "from pinecone import Pinecone\n", - "\n", - "# Instantiate a Pinecone client\n", - "pc = Pinecone(api_key=os.environ.get(\"PINECONE_API_KEY\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Creating a Pinecone Index\n", - "\n", - "When creating the index we need to define several configuration properties. \n", - "\n", - "- `name` can be anything we like. The name is used as an identifier for the index when performing other operations such as `describe_index`, `delete_index`, and so on. \n", - "- `metric` specifies the similarity metric that will be used later when you make queries to the index.\n", - "- `dimension` should correspond to the dimension of the dense vectors produced by your embedding model. In this quick start, we are using made-up data so a small value is simplest.\n", - "- `spec` holds a specification which tells Pinecone how you would like to deploy our index. You can find a list of all [available providers and regions here](https://docs.pinecone.io/docs/projects).\n", - "\n", - "There are more configurations available, but this minimal set will get us started." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "9pT9C4nW4vwo", - "outputId": "6aea8f5a-9331-4c20-c967-989c668ac681" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{\n", - " \"name\": \"langchain-retrieval-augmentation-fast\",\n", - " \"dimension\": 1536,\n", - " \"metric\": \"dotproduct\",\n", - " \"host\": \"langchain-retrieval-augmentation-fast-dojoi3u.svc.aped-4627-b74a.pinecone.io\",\n", - " \"spec\": {\n", - " \"serverless\": {\n", - " \"cloud\": \"aws\",\n", - " \"region\": \"us-east-1\"\n", - " }\n", - " },\n", - " \"status\": {\n", - " \"ready\": true,\n", - " \"state\": \"Ready\"\n", - " },\n", - " \"deletion_protection\": \"disabled\"\n", - "}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pinecone import ServerlessSpec\n", - "\n", - "index_name = 'langchain-retrieval-augmentation-fast'\n", - "\n", - "if not pc.has_index(name=index_name):\n", - " pc.create_index(\n", - " name=index_name,\n", - " dimension=1536, # dimensionality of text-embedding-ada-002\n", - " metric='dotproduct',\n", - " spec=ServerlessSpec(\n", - " cloud='aws',\n", - " region='us-east-1'\n", - " )\n", - " )\n", - "\n", - "pc.describe_index(name=index_name)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "YgPUwd6REY6z" - }, - "source": [ - "## Upserting data into the index" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "RFydARw4EcoQ", - "outputId": "92cbb1cf-bb70-4b3a-a481-ede66a5dc7b0" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'dimension': 1536,\n", - " 'index_fullness': 0.0,\n", - " 'namespaces': {'': {'vector_count': 50000}},\n", - " 'total_vector_count': 50000}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Instantiate an Index client\n", - "index = pc.Index(name=index_name)\n", - "\n", - "index.describe_index_stats()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "0RqIF2mIDwFu" - }, - "source": [ - "We should see that the new Pinecone index initially has a `total_vector_count` of `0`, as we haven't added any vectors yet.\n", - "\n", - "Now we upsert the data to Pinecone:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 99, - "referenced_widgets": [ - "47188360f07a4c018bf7d2c5eb6f626c", - "50d346f4ff614f8cb7793cce0a9c0916", - "f06f0a851b6c434da5cd9ddb245de902", - "3216e01669cc470894d25198a2099263", - "47ecdc632edf4aeeb37239510aff8ced", - "2ee36ac5673a4b74877dcf3fe63c5eb3", - "f948308ac3414cfabbea8e2af917446f", - "21045e189c5d49a082964eec2c5d8f6a", - "4981784e865746a49a912188fb599985", - "07c3ae73ab9b4c66813d1646ce6a320d", - "6acfe82fd33043558667ac26141093f8", - "75cef31e615d4851b029c3aacacf9c2d", - "6b3b8cddec674c0bb00620e1c9128219", - "54d772726617494d98e5ee1618db5cf0", - "34b9b178e43a4cc1ba516c4f27ffd575", - "0021290a0a3a44be911c4e94b7d25006", - "7f7790181f72437cb10a88704d20f778", - "62da3ff6ab334122aa0657a6f25417bb", - "2d038c3eb946427297de35460a8d4ae2", - "5f0fb5f8cfb7459d80f6a92bd0125dcb", - "6e1f19542e2645ccad3a8c99bf6e030b", - "7c834ff3591545f7809a46989c3a985b" - ] - }, - "id": "W-cIOoTWGY1R", - "outputId": "0eaf686b-ee21-47ca-e818-f29fb768e3c1" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Upserting records batch: 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 500/500 [07:07<00:00, 1.17it/s]\n" - ] - } - ], - "source": [ - "from tqdm import tqdm\n", - "\n", - "batch_size = 100\n", - "\n", - "for start in tqdm(range(0, len(dataset.documents), batch_size), \"Upserting records batch\"):\n", - " batch = dataset.documents.iloc[start:start + batch_size].to_dict(orient=\"records\")\n", - " index.upsert(vectors=batch)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "XaF3daSxyCwB" - }, - "source": [ - "We've now indexed everything. We can check the number of vectors in our index again using `describe_index_stats()`.\n", - "\n", - "We may see that the `total_vector_count` is a bit less than the total we expect (50K). This is because Pinecone is eventually consistent and not all vectors may be reflected in the index yet." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "CaEBhsAM22M3", - "outputId": "9718d994-c8e1-4ff3-ae1d-b57b9b1d3c46" - }, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'index' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mindex\u001b[49m\u001b[38;5;241m.\u001b[39mdescribe_index_stats()\n", - "\u001b[0;31mNameError\u001b[0m: name 'index' is not defined" - ] - } - ], - "source": [ - "index.describe_index_stats()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "-8P2PryCy8W3" - }, - "source": [ - "## Creating a Langchain Vector Store and Querying\n", - "\n", - "Now that we've build our index we can switch over to LangChain. We need to initialize a LangChain vector store using the same index we just built. For this we will also need a LangChain embedding object, which we initialize like so:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "id": "FvwwQA4qbcK9" - }, - "outputs": [], - "source": [ - "from langchain_openai import OpenAIEmbeddings\n", - "\n", - "# Get openai api key from platform.openai.com\n", - "OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') or 'OPENAI_API_KEY'\n", - "\n", - "model_name = 'text-embedding-ada-002'\n", - "\n", - "embed = OpenAIEmbeddings(\n", - " model=model_name,\n", - " openai_api_key=OPENAI_API_KEY\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "jKuedXN8bcfA" - }, - "source": [ - "Now initialize the vector store:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "id": "qMXlvXOAyJHy" - }, - "outputs": [], - "source": [ - "from langchain_pinecone import PineconeVectorStore\n", - "\n", - "pinecone_vectorstore = PineconeVectorStore(\n", - " index_name=index_name, \n", - " embedding=embed, \n", - " text_key=\"text\"\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "h1Yg5mKse1bO" - }, - "source": [ - "Now we can query the vector store directly using `pinecone_vectorstore.similarity_search`:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "COT5s7hcyPiq", - "outputId": "4373a9bb-682f-4000-a491-2c948b9b44f2" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'id': '6754-0',\n", - " 'metadata': {'chunk': 0.0,\n", - " 'source': 'https://simple.wikipedia.org/wiki/Benito%20Mussolini',\n", - " 'title': 'Benito Mussolini',\n", - " 'wiki-id': '6754'},\n", - " 'page_content': 'Benito Amilcare Andrea Mussolini KSMOM GCTE (29 July 1883 \u2013 '\n", - " '28 April 1945) was an Italian politician and journalist. He '\n", - " 'was also the Prime Minister of Italy from 1922 until 1943. '\n", - " 'He was the leader of the National Fascist Party.\\n'\n", - " '\\n'\n", - " 'Biography\\n'\n", - " '\\n'\n", - " 'Early life\\n'\n", - " 'Benito Mussolini was named after Benito Juarez, a Mexican '\n", - " 'opponent of the political power of the Roman Catholic '\n", - " 'Church, by his anticlerical (a person who opposes the '\n", - " 'political interference of the Roman Catholic Church in '\n", - " \"secular affairs) father. Mussolini's father was a \"\n", - " 'blacksmith. Before being involved in politics, Mussolini was '\n", - " 'a newspaper editor (where he learned all his propaganda '\n", - " 'skills) and elementary school teacher.\\n'\n", - " '\\n'\n", - " 'At first, Mussolini was a socialist, but when he wanted '\n", - " 'Italy to join the First World War, he was thrown out of the '\n", - " \"socialist party. He 'invented' a new ideology, Fascism, much \"\n", - " 'out of Nationalist\\xa0and Conservative views.\\n'\n", - " '\\n'\n", - " 'Rise to power and becoming dictator\\n'\n", - " 'In 1922, he took power by having a large group of men, '\n", - " '\"Black Shirts,\" march on Rome and threaten to take over the '\n", - " 'government. King Vittorio Emanuele III gave in, allowed him '\n", - " 'to form a government, and made him prime minister. In the '\n", - " 'following five years, he gained power, and in 1927 created '\n", - " 'the OVRA, his personal secret police force. Using the agency '\n", - " 'to arrest, scare, or murder people against his regime, '\n", - " 'Mussolini was dictator\\xa0of Italy by the end of 1927. Only '\n", - " 'the King and his own Fascist party could challenge his '\n", - " 'power.',\n", - " 'type': 'Document'}\n", - "\n", - "{'id': '6754-1',\n", - " 'metadata': {'chunk': 1.0,\n", - " 'source': 'https://simple.wikipedia.org/wiki/Benito%20Mussolini',\n", - " 'title': 'Benito Mussolini',\n", - " 'wiki-id': '6754'},\n", - " 'page_content': 'Fascism as practiced by Mussolini\\n'\n", - " 'Mussolini\\'s form of Fascism, \"Italian Fascism\"- unlike '\n", - " 'Nazism, the racist ideology that Adolf Hitler followed- was '\n", - " \"different and less destructive than Hitler's. Although a \"\n", - " 'believer in the superiority of the Italian nation and '\n", - " 'national unity, Mussolini, unlike Hitler, is quoted \"Race? '\n", - " 'It is a feeling, not a reality. Nothing will ever make me '\n", - " 'believe that biologically pure races can be shown to exist '\n", - " 'today\".\\n'\n", - " '\\n'\n", - " 'Mussolini wanted Italy to become a new Roman Empire. In '\n", - " '1923, he attacked the island of Corfu, and in 1924, he '\n", - " 'occupied the city state of Fiume. In 1935, he attacked the '\n", - " 'African country Abyssinia (now called Ethiopia). His forces '\n", - " 'occupied it in 1936. Italy was thrown out of the League of '\n", - " 'Nations because of this aggression. In 1939, he occupied the '\n", - " 'country Albania. In 1936, Mussolini signed an alliance with '\n", - " 'Adolf Hitler, the dictator of Germany.\\n'\n", - " '\\n'\n", - " 'Fall from power and death\\n'\n", - " 'In 1940, he sent Italy into the Second World War on the side '\n", - " 'of the Axis countries. Mussolini attacked Greece, but he '\n", - " 'failed to conquer it. In 1943, the Allies landed in Southern '\n", - " 'Italy. The Fascist party and King Vittorio Emanuel III '\n", - " 'deposed Mussolini and put him in jail, but he was set free '\n", - " 'by the Germans, who made him ruler of the Italian Social '\n", - " 'Republic puppet state which was in a small part of Central '\n", - " 'Italy. When the war was almost over, Mussolini tried to '\n", - " 'escape to Switzerland with his mistress, Clara Petacci, but '\n", - " \"they were both captured and shot by partisans. Mussolini's \"\n", - " 'dead body was hanged upside-down, together with his mistress '\n", - " \"and some of Mussolini's helpers, on a pole at a gas station \"\n", - " 'in the village of Millan, which is near the border between '\n", - " 'Italy and Switzerland.',\n", - " 'type': 'Document'}\n", - "\n", - "{'id': '363-5',\n", - " 'metadata': {'chunk': 5.0,\n", - " 'source': 'https://simple.wikipedia.org/wiki/Italy',\n", - " 'title': 'Italy',\n", - " 'wiki-id': '363'},\n", - " 'page_content': 'Veneto was made part of Italy in 1866 after a war with '\n", - " 'Austria. Italian soldiers won Latium in 1870. That was when '\n", - " \"they took away the Pope's power. The Pope, who was angry, \"\n", - " 'said that he was a prisoner to keep Catholic people from '\n", - " 'being active in politics. That was the year of Italian '\n", - " 'unification.\\n'\n", - " '\\n'\n", - " 'Italy participated in World War I. It was an ally of Great '\n", - " 'Britain, France, and Russia against the Central Powers. '\n", - " \"Almost all of Italy's fighting was on the Eastern border, \"\n", - " 'near Austria. After the \"Caporetto defeat\", Italy thought '\n", - " 'they would lose the war. But, in 1918, the Central Powers '\n", - " 'surrendered. Italy gained the Trentino-South Tyrol, which '\n", - " 'once was owned by Austria.\\n'\n", - " '\\n'\n", - " 'Fascist Italy \\n'\n", - " 'In 1922, a new Italian government started. It was ruled by '\n", - " 'Benito Mussolini, the leader of Fascism in Italy. He became '\n", - " 'head of government and dictator, calling himself \"Il Duce\" '\n", - " '(which means \"leader\" in Italian). He became friends with '\n", - " 'German dictator Adolf Hitler. Germany, Japan, and Italy '\n", - " 'became the Axis Powers. In 1940, they entered World War II '\n", - " 'together against France, Great Britain, and later the Soviet '\n", - " 'Union. During the war, Italy controlled most of the '\n", - " 'Mediterranean Sea.',\n", - " 'type': 'Document'}\n", - "\n" - ] - } - ], - "source": [ - "from pprint import pprint\n", - "\n", - "documents = pinecone_vectorstore.similarity_search(\n", - " query=\"Who was Benito Mussolini?\", # our search query\n", - " k=3 # return 3 most relevant docs\n", - ")\n", - "\n", - "for doc in documents:\n", - " pprint(doc.__dict__)\n", - " print()" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "SMFUgtvbFeLQ" + }, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/langchain-retrieval-augmentation.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/docs/langchain-retrieval-augmentation.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v0to-QXCQjsm" + }, + "source": [ + "# Retrieval-Augmented Generation with Pinecone, LangChain and OpenAI\n", + "\n", + "## Fixing LLMs that Hallucinate\n", + "\n", + "In this notebook, you'll learn one of the most common applications of retrieval-augmented generation: giving large language models access to up-to-date information. \n", + "\n", + "\n", + "### Demo Data: Pinecone Documentation\n", + "\n", + "A great example to use RAG is when augmenting LLMs with information that may not exist in their training data. This could private data, internal company information, or data that has been updated post a training cutoff. In our case, many modern LLMs are rained on Pinecone data that has since been updated, such as release notes, quickstart guides, blog posts, docs, and code.\n", + "\n", + "In this example, we'll show the differences in generation from OpenAI's LLMs when asked about Pinecone's release notes! We'll orchestrate our RAG workflow using LangChain, a popular framework for AI applications." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "ZCvtmREd0pdo" - }, - "source": [ - "All of these are good, relevant results. But what can we do with this? There are many tasks, one of the most interesting (and well supported by LangChain) is called _\"Generative Question-Answering\"_ or GQA.\n", - "\n", - "## Generative Question-Answering\n", - "\n", - "In GQA we take the query as a question that is to be answered by a LLM, but the LLM must answer the question based on the information it is seeing being returned from the `vectorstore`.\n", - "\n", - "To do this we initialize a `RetrievalQA` object like so:" - ] + "id": "VpMvHAYRQf9N", + "outputId": "42705370-c5bf-417b-fe8a-3f6d0fe28fbb" + }, + "outputs": [], + "source": [ + "!pip install -qU \\\n", + " \"langchain[openai]\"\\\n", + " langchain-text-splitters==0.3.8 \\\n", + " langchain-pinecone==0.2.1 \\\n", + " pinecone-notebooks==0.1.1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NhWnLkHqmeWI" + }, + "source": [ + "---\n", + "\n", + "## Building a Knowledge Base with our Vector Database\n", + "\n", + "Building more reliable LLMs tools requires an external _\"Knowledge Base\"_, a database that we can query and update periodically with information.\n", + "\n", + "Specifically, we will need to retrieve information that is relevant to our queries. To do this we need to use _\"dense vector embeddings\"_. These can be thought of as numerical representations of the *meaning* behind our sentences.\n", + "\n", + "There are many options for creating these dense vectors, like open source [sentence transformers embedding models](https://www.pinecone.io/learn/series/nlp/) or OpenAI's [text-embedding-3-small model](https://platform.openai.com/docs/models/text-embedding-3-small). We will use OpenAI's offering in this example.\n", + "\n", + "### Before you begin...\n", + "\n", + "Be sure to grab a [free Pinecone account](https://app.pinecone.io/?sessionType=signup) and an OpenAI API key, [located here](https://platform.openai.com/api-keys)!" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "## Getting our Dataset: \n", + "\n", + "# These are markdown versions of our release notes from 2025 and 2024\n", + "release_notes_2025 = \"https://docs.pinecone.io/release-notes/2025.md\"\n", + "release_notes_2024 = \"https://docs.pinecone.io/release-notes/2024.md\"\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Preprocessing our data\n", + "\n", + "We'll use Requests and LangChain to pull down the release notes, and process the associated Markdown. We've used splitters that correspond to the release year, month/year, and features. \n", + "This will take us from raw Markdown files to LangChain Documents, which we'll embed and store in Pinecone." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 }, + "id": "EI2iYxq16or9", + "outputId": "55a8dd92-34e1-4237-a5c4-76016346999d" + }, + "outputs": [], + "source": [ + "# We'll grab these urls and parse them using LangChain's textsplitter for markdown\n", + "from langchain_text_splitters import MarkdownHeaderTextSplitter\n", + "from langchain_core.documents import Document\n", + "import requests\n", + "\n", + "splitter = MarkdownHeaderTextSplitter(headers_to_split_on=[(\"#\", \"release\"), (\"##\", \"month_year\"), (\"###\", \"feature\")])\n", + "\n", + "def download_link(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " return response.text\n", + "\n", + "\n", + "def add_document_metadata(doc, new_metadata):\n", + " # returns new documents with updated metadata\n", + " old_metadata = doc.metadata\n", + " new_metadata = {**old_metadata, **new_metadata}\n", + " return Document(page_content=doc.page_content, metadata=new_metadata)\n", + "\n", + "\n", + "def preprocess_pinecone_docs(urls):\n", + "\n", + " pinecone_docs = []\n", + " for url in urls:\n", + " # download the markdown\n", + " response = download_link(url)\n", + " split_text = splitter.split_text(response)\n", + " # Update metadata to include url as source \n", + " split_text = [add_document_metadata(doc, {\"source\": url, \"chunk_num\": num}) for num, doc in enumerate(split_text)]\n", + " pinecone_docs.extend(split_text)\n", + " return pinecone_docs\n", + "\n", + "\n", + "pinecone_docs = preprocess_pinecone_docs([release_notes_2024,release_notes_2025])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's take a closer look at one of these notes" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "id": "moCvQR-p0Zsb" - }, - "outputs": [], - "source": [ - "from langchain_openai import ChatOpenAI\n", - "from langchain.chains import RetrievalQA\n", - "\n", - "# Chat Completion LLM\n", - "llm = ChatOpenAI(\n", - " openai_api_key=OPENAI_API_KEY,\n", - " model_name='gpt-4.5-preview',\n", - " temperature=0.0\n", - ")\n", - "\n", - "qa = RetrievalQA.from_chain_type(\n", - " llm=llm,\n", - " chain_type=\"stuff\",\n", - " retriever=pinecone_vectorstore.as_retriever()\n", - ")" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "Document content: Pinecone Assistant can now [return a JSON response](/guides/assistant/chat-with-assistant#json-response). \n", + "*** \n", + "You can now [create an assistant](/reference/api/2025-01/assistant/create_assistant) in the `eu` region.\n", + " \n", + "\n", + "Document metadata: {'release': '2024 releases', 'month_year': 'December 2024', 'feature': 'Pinecone Assistant JSON mode and EU region deployment', 'source': 'https://docs.pinecone.io/release-notes/2024.md', 'chunk_num': 2}\n" + ] + } + ], + "source": [ + "print(\"Document content: \", pinecone_docs[2].page_content)\n", + "print(\"Document metadata: \", pinecone_docs[2].metadata)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 106 - }, - "id": "KS9sa19K3LkQ", - "outputId": "d7473cc3-6c7a-44c3-e219-12396eeb5580" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'query': 'Who was Benito Mussolini?',\n", - " 'result': 'Benito Mussolini was an Italian politician and journalist who served as the Prime Minister of Italy from 1922 until 1943. He was the leader of the National Fascist Party and established a dictatorship in Italy, calling himself \"Il Duce\" (meaning \"leader\" in Italian). Initially a socialist, Mussolini was expelled from the socialist party due to his support for Italy\\'s involvement in World War I. He then created a new political ideology known as Fascism, which emphasized nationalism, authoritarianism, and strong centralized control.\\n\\nMussolini rose to power in 1922 after organizing the \"March on Rome,\" where his supporters, known as the \"Black Shirts,\" threatened to seize control of the government. King Vittorio Emanuele III appointed him Prime Minister, and by 1927 Mussolini had consolidated power, establishing a dictatorship enforced by his secret police, the OVRA.\\n\\nMussolini aimed to restore Italy to the glory of the ancient Roman Empire, leading aggressive military campaigns in places like Ethiopia (then Abyssinia), Albania, and Greece. He allied Italy with Nazi Germany and Japan during World War II, forming the Axis Powers. However, Italy suffered military defeats, and in 1943 Mussolini was removed from power and imprisoned. He was later rescued by German forces and installed as the leader of a puppet state in Northern Italy, the Italian Social Republic.\\n\\nIn April 1945, as World War II was ending, Mussolini attempted to flee to Switzerland but was captured and executed by Italian partisans along with his mistress, Clara Petacci. Their bodies were publicly displayed in Milan.'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "qa.invoke(\"Who was Benito Mussolini?\")" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "Document content: Released [`v2.2.0`](https://github.com/pinecone-io/go-pinecone/releases/tag/v2.2.0) of the [Pinecone Go SDK](/reference/go-sdk). This version adds support for [index tags](/guides/manage-data/manage-indexes#configure-index-tags) when creating or configuring indexes.\n", + "\n", + "Document metadata: {'release': '2025 releases', 'month_year': 'January 2025', 'feature': 'Released Go SDK v2.2.0', 'source': 'https://docs.pinecone.io/release-notes/2025.md', 'chunk_num': 47}\n" + ] + } + ], + "source": [ + "print(\"Document content: \", pinecone_docs[-1].page_content)\n", + "print(\"Document metadata: \", pinecone_docs[-1].metadata)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up Pinecone\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we'll setup our API keys. For notebooks in Colab environments, we've included a handy block that helps set a Pinecone API key in your environment. In all other contexts, it's sufficient to save your Pinecone and OpenAI keys in your local environment. \n", + "\n", + "Run the next two blocks and enter your Pinecone and OpenAI keys as needed:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "0qf5e3xf3ggq" - }, - "source": [ - "We can also include the sources of information that the LLM is using to answer our question. We can do this using a slightly different version of `RetrievalQA` called `RetrievalQAWithSourcesChain`:" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "Pinecone API key not found in environment.\n" + ] + } + ], + "source": [ + "\n", + "import os\n", + "from getpass import getpass\n", + "\n", + "def get_pinecone_api_key():\n", + " \"\"\"\n", + " Get Pinecone API key from environment variable or prompt user for input.\n", + " Returns the API key as a string.\n", + "\n", + " Only necessary for notebooks. When using Pinecone yourself, \n", + " you can use environment variables or the like to set your API key.\n", + " \"\"\"\n", + " api_key = os.environ.get(\"PINECONE_API_KEY\")\n", + " \n", + " if api_key is None:\n", + " try:\n", + " # Try Colab authentication if available\n", + " from pinecone_notebooks.colab import Authenticate\n", + " Authenticate()\n", + " # If successful, key will now be in environment\n", + " api_key = os.environ.get(\"PINECONE_API_KEY\")\n", + " except ImportError:\n", + " # If not in Colab or authentication fails, prompt user for API key\n", + " print(\"Pinecone API key not found in environment.\")\n", + " api_key = getpass(\"Please enter your Pinecone API key: \")\n", + " # Save to environment for future use in session\n", + " os.environ[\"PINECONE_API_KEY\"] = api_key\n", + " \n", + " return api_key\n", + "\n", + "PINECONE_API_KEY = get_pinecone_api_key()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup OpenAI API Key\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def get_openai_api_key():\n", + " \"\"\"\n", + " Get OpenAI API key from environment variable or prompt user for input.\n", + " Returns the API key as a string.\n", + " \"\"\"\n", + "\n", + " api_key = os.environ.get(\"OPENAI_API_KEY\")\n", + " \n", + " if api_key is None:\n", + " try:\n", + " api_key = getpass(\"Please enter your OpenAI API key: \")\n", + " # Save to environment for future use in session\n", + " os.environ[\"OPENAI_API_KEY\"] = api_key\n", + " except Exception as e:\n", + " print(f\"Error getting OpenAI API key: {e}\")\n", + " return None\n", + " \n", + " return api_key" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "OPENAI_API_KEY = get_openai_api_key()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up Pinecone Index\n", + "We'll instantiate a Pinecone client, and create an index with a few key properties:\n", + "- index_name, which identifies our index\n", + "- dimension, which corresponds to the OpenAI embedding model vector size we'll use\n", + "- metric, which corresponds to the way \"closeness\" is evaluated with our vectors\n", + "- a spec, which determines the kind of index we are setting up. In this case, it's a free tier Pinecone serverless index" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "id": "aYVMGDA13cTz" - }, - "outputs": [], - "source": [ - "from langchain.chains import RetrievalQAWithSourcesChain\n", - "\n", - "qa_with_sources = RetrievalQAWithSourcesChain.from_chain_type(\n", - " llm=llm,\n", - " chain_type=\"stuff\",\n", - " retriever=pinecone_vectorstore.as_retriever(),\n", - " return_source_documents=True\n", - ")" - ] - }, + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/miniconda3/envs/pinecone-examples/lib/python3.11/site-packages/pinecone/data/index.py:1: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from tqdm.autonotebook import tqdm\n" + ] + } + ], + "source": [ + "from pinecone import Pinecone\n", + "\n", + "pc = Pinecone(\n", + " api_key=PINECONE_API_KEY,\n", + " # You can remove this parameterfor your own projects\n", + " source_tag=\"pinecone_examples:docs:langchain_retrieval_augmentation\"\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "RXsVEh3S4ZJO", - "outputId": "4150e3c6-3210-439b-9c85-389d8c20d02b" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'question': 'Who was Benito Mussolini?',\n", - " 'answer': 'Benito Mussolini was an Italian politician and journalist who served as the Prime Minister of Italy from 1922 until 1943. He was the leader of the National Fascist Party and established a dictatorship in Italy. Mussolini initially was a socialist but later created the ideology of Fascism, combining nationalist and conservative views. He rose to power through the March on Rome in 1922, eventually becoming dictator by 1927. Mussolini aimed to create a new Roman Empire, engaging in aggressive military actions such as invading Abyssinia (Ethiopia) and Albania. He allied with Adolf Hitler during World War II, forming part of the Axis Powers. Mussolini was deposed in 1943, briefly reinstated by the Germans as head of a puppet state, and was ultimately captured and executed by partisans in 1945.\\n\\n',\n", - " 'sources': '',\n", - " 'source_documents': [Document(id='6754-0', metadata={'chunk': 0.0, 'source': 'https://simple.wikipedia.org/wiki/Benito%20Mussolini', 'title': 'Benito Mussolini', 'wiki-id': '6754'}, page_content='Benito Amilcare Andrea Mussolini KSMOM GCTE (29 July 1883 \u2013 28 April 1945) was an Italian politician and journalist. He was also the Prime Minister of Italy from 1922 until 1943. He was the leader of the National Fascist Party.\\n\\nBiography\\n\\nEarly life\\nBenito Mussolini was named after Benito Juarez, a Mexican opponent of the political power of the Roman Catholic Church, by his anticlerical (a person who opposes the political interference of the Roman Catholic Church in secular affairs) father. Mussolini\\'s father was a blacksmith. Before being involved in politics, Mussolini was a newspaper editor (where he learned all his propaganda skills) and elementary school teacher.\\n\\nAt first, Mussolini was a socialist, but when he wanted Italy to join the First World War, he was thrown out of the socialist party. He \\'invented\\' a new ideology, Fascism, much out of Nationalist\\xa0and Conservative views.\\n\\nRise to power and becoming dictator\\nIn 1922, he took power by having a large group of men, \"Black Shirts,\" march on Rome and threaten to take over the government. King Vittorio Emanuele III gave in, allowed him to form a government, and made him prime minister. In the following five years, he gained power, and in 1927 created the OVRA, his personal secret police force. Using the agency to arrest, scare, or murder people against his regime, Mussolini was dictator\\xa0of Italy by the end of 1927. Only the King and his own Fascist party could challenge his power.'),\n", - " Document(id='6754-1', metadata={'chunk': 1.0, 'source': 'https://simple.wikipedia.org/wiki/Benito%20Mussolini', 'title': 'Benito Mussolini', 'wiki-id': '6754'}, page_content='Fascism as practiced by Mussolini\\nMussolini\\'s form of Fascism, \"Italian Fascism\"- unlike Nazism, the racist ideology that Adolf Hitler followed- was different and less destructive than Hitler\\'s. Although a believer in the superiority of the Italian nation and national unity, Mussolini, unlike Hitler, is quoted \"Race? It is a feeling, not a reality. Nothing will ever make me believe that biologically pure races can be shown to exist today\".\\n\\nMussolini wanted Italy to become a new Roman Empire. In 1923, he attacked the island of Corfu, and in 1924, he occupied the city state of Fiume. In 1935, he attacked the African country Abyssinia (now called Ethiopia). His forces occupied it in 1936. Italy was thrown out of the League of Nations because of this aggression. In 1939, he occupied the country Albania. In 1936, Mussolini signed an alliance with Adolf Hitler, the dictator of Germany.\\n\\nFall from power and death\\nIn 1940, he sent Italy into the Second World War on the side of the Axis countries. Mussolini attacked Greece, but he failed to conquer it. In 1943, the Allies landed in Southern Italy. The Fascist party and King Vittorio Emanuel III deposed Mussolini and put him in jail, but he was set free by the Germans, who made him ruler of the Italian Social Republic puppet state which was in a small part of Central Italy. When the war was almost over, Mussolini tried to escape to Switzerland with his mistress, Clara Petacci, but they were both captured and shot by partisans. Mussolini\\'s dead body was hanged upside-down, together with his mistress and some of Mussolini\\'s helpers, on a pole at a gas station in the village of Millan, which is near the border between Italy and Switzerland.'),\n", - " Document(id='363-5', metadata={'chunk': 5.0, 'source': 'https://simple.wikipedia.org/wiki/Italy', 'title': 'Italy', 'wiki-id': '363'}, page_content='Veneto was made part of Italy in 1866 after a war with Austria. Italian soldiers won Latium in 1870. That was when they took away the Pope\\'s power. The Pope, who was angry, said that he was a prisoner to keep Catholic people from being active in politics. That was the year of Italian unification.\\n\\nItaly participated in World War I. It was an ally of Great Britain, France, and Russia against the Central Powers. Almost all of Italy\\'s fighting was on the Eastern border, near Austria. After the \"Caporetto defeat\", Italy thought they would lose the war. But, in 1918, the Central Powers surrendered. Italy gained the Trentino-South Tyrol, which once was owned by Austria.\\n\\nFascist Italy \\nIn 1922, a new Italian government started. It was ruled by Benito Mussolini, the leader of Fascism in Italy. He became head of government and dictator, calling himself \"Il Duce\" (which means \"leader\" in Italian). He became friends with German dictator Adolf Hitler. Germany, Japan, and Italy became the Axis Powers. In 1940, they entered World War II together against France, Great Britain, and later the Soviet Union. During the war, Italy controlled most of the Mediterranean Sea.'),\n", - " Document(id='363-4', metadata={'chunk': 4.0, 'source': 'https://simple.wikipedia.org/wiki/Italy', 'title': 'Italy', 'wiki-id': '363'}, page_content='The head of government is Mario Draghi. He became Prime Minister on February 13, 2021. He succeeded Giuseppe Conte. Conte\\'s cabinet, fell after a political crisis caused by Italia Viva, a liberal political party.\\n\\nItaly was one of the first members of the European Union. In 2002 along with 11 other European countries, it changed to using the euro as its official currency. Before this, the Italian lira had been used since 1861.\\n\\nAnyone who wants to be President of Italy must have Italian citizenship, be at least 50 years old, and must be able to hold political and civil rights.\\n\\nHistory \\n\\nIn ancient times, the capital of Italy was Rome. Rome was founded in 753 BC. It was a separate state well known as Roman Kingdom firstly, Roman Republic and Roman Empire later.\\n\\nBefore 1861, Italy was not a state. The area included a group of separate states that were ruled by other countries (such as Austria, France, and Spain). In the 1850s, the Earl of Camillo Benso, Count of Cavour was the head of government of the \"State of Sardinia\". He talked to the Austrians in Lombardy and Veneto and said they should create a Northern Italian state. This happened, but other Central and Southern Italian states also joined Piedmont to create a bigger state.\\n\\nKingdom of Italy \\n\\nIn 1860, Giuseppe Garibaldi took control of Sicily, creating the Kingdom of Italy in 1861. Victor Emmanuel II was made the king. In 1861, Latium and Veneto were still not part of Italy, because they were ruled by the Pope and Austrian Empire.')]}" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "qa_with_sources.invoke(\"Who was Benito Mussolini?\")" + "data": { + "text/plain": [ + "{'dimension': 1536,\n", + " 'index_fullness': 0.0,\n", + " 'namespaces': {},\n", + " 'total_vector_count': 0}" ] - }, + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index_name = \"langchain-pinecone-rag\"\n", + "from pinecone import ServerlessSpec\n", + "\n", + "if not pc.has_index(index_name):\n", + " pc.create_index(\n", + " name=index_name,\n", + " # dimension of the vector embeddings produced by OpenAI's text-embedding-3-small\n", + " dimension=1536,\n", + " metric=\"cosine\",\n", + " # parameters for the free tier index\n", + " spec=ServerlessSpec(\n", + " cloud=\"aws\",\n", + " region=\"us-east-1\"\n", + " )\n", + " )\n", + "\n", + "# Initialize index client\n", + "index = pc.Index(name=index_name)\n", + "\n", + "# View index stats\n", + "index.describe_index_stats()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Embedding our documents and upserting into Pinecone" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we'll setup our OpenAI embedding model and Pinecone vector database within LangChain. To do this, we import the related abstractions from LangChain and pass in our API keys and model names.\n", + "\n", + "After that, we generate ids for each document-chunk to better manage them within Pinecone." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "nMRk_P3Q7l5J" - }, - "source": [ - "Now we answer the question being asked, *and* return the source of this information being used by the LLM." + "data": { + "text/plain": [ + "[{'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 0},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Increased namespaces limit',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 1},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Pinecone Assistant JSON mode and EU region deployment',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 2},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Released Spark-Pinecone connector v1.2.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 3},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'New integration with HoneyHive',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 4},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Released Python SDK v5.4.2',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 5},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Launch week: Pinecone Local',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 6},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Launch week: Enhanced security and access controls',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 7},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Launch week: `pinecone-rerank-v0` and `cohere-rerank-3.5` on Pinecone Inference',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 8},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Launch week: Integrated Inference',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 9},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Released .NET SDK v2.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 10},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Improved batch deletion guidance',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 11},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'December 2024',\n", + " 'feature': 'Launch week: Released `pinecone-sparse-english-v0`',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 12},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 13},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Pinecone docs: New workflows and best practices',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 14},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Released Java SDK v3.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 15},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Pinecone Assistant: Context snippets and structured data files',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 16},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Monthly spend alerts',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 17},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Released .NET SDK v2.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 18},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Released Python SDK v5.4.0 and v5.4.1',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 19},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Enabled CSV export of usage and costs',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 20},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Added Support chat in the console',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 21},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'November 2024',\n", + " 'feature': 'Published Assistant quickstart guide',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 22},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 23},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Cequence released updated Scala SDK',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 24},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Added index tagging for categorization',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 25},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Released major SDK updates: Node.js, Go, Java, and Python',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 26},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Pinecone API version `2024-10` is now the latest stable version',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 27},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Pinecone Inference now available on the free Starter plan',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 28},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Customer-managed encryption keys (CMEK) in early access',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 29},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Serverless index monitoring generally available',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 30},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Data import from Amazon S3 in public preview',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 31},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'October 2024',\n", + " 'feature': 'Chat and update features added to Assistant',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 32},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'September 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 33},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'August 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 34},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'July 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 35},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'June 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 36},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'May 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 37},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'April 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 38},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'March 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 39},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'February 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 40},\n", + " {'release': '2024 releases',\n", + " 'month_year': 'January 2024',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2024.md',\n", + " 'chunk_num': 41},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'June 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 0},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'June 2025',\n", + " 'feature': 'Released Java SDK v5.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 1},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'June 2025',\n", + " 'feature': 'Released Node.js SDK v6.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 2},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 3},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released Python SDK v7.0.1 and v7.0.2',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 4},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released Node.s SDK v6.0.1',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 5},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Pinecone API version `2025-04` is now the latest stable version',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 6},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released Python SDK v7.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 7},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released Node.js SDK v6.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 8},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released Java SDK v5.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 9},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'Released .NET SDK v4.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 10},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'May 2025',\n", + " 'feature': 'New Docs IA',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 11},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 12},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Bring Your Own Cloud (BYOC) in GCP',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 13},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Integrate AI agents with Pinecone MCP',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 14},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Add context to AI agents with Assistant MCP',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 15},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Upload a file from an in-memory binary stream',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 16},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Released Pinecone Terraform Provider v1.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 17},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'Released .NET SDK v3.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 18},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'April 2025',\n", + " 'feature': 'LLM shortcuts for Pinecone docs',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 19},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 20},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Control the context snippets the assistant sends to the LLM',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 21},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Released Go SDK v3.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 22},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Launch week: Dark mode',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 23},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Launch week: Self-service audit logs',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 24},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Launch week: Introducing the Admin API and service accounts',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 25},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Launch week: Back up an index through the API',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 26},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Launch week: Optimized database architecture',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 27},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Firebase Genkit integration',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 28},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'March 2025',\n", + " 'feature': 'Bring Your Own Cloud (BYOC) in public preview',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 29},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 30},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Docs site refresh',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 31},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Limit the number of chunks retrieved',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 32},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Assistant Quickstart colab notebook',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 33},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Released Node.js SDK v5.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 34},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'New integrations',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 35},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Citation highlights in assistant responses',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 36},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Pinecone API version `2025-01` is now the latest stable version',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 37},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Released Python SDK v6.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 38},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Released Java SDK v4.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 39},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Released Go SDK v3.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 40},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'February 2025',\n", + " 'feature': 'Released .NET SDK v3.0.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 41},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 42},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'feature': 'Update to the API keys page',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 43},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'feature': 'Sparse-only indexes in early access',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 44},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'feature': 'Released Node SDK v4.1.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 45},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'feature': 'New Billing Admin user role',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 46},\n", + " {'release': '2025 releases',\n", + " 'month_year': 'January 2025',\n", + " 'feature': 'Released Go SDK v2.2.0',\n", + " 'source': 'https://docs.pinecone.io/release-notes/2025.md',\n", + " 'chunk_num': 47}]" ] - }, + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[doc.metadata for doc in pinecone_docs]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Demo cleanup\n", - "\n", - "Once you're done, you can free up resources by deleting your index. Deleting an index is a permanet operation and cannot be undone." + "data": { + "text/plain": [ + "['release_2024#feature_na#chunk_num0',\n", + " 'release_2024#feature_Increased namespaces limit#chunk_num1',\n", + " 'release_2024#feature_Pinecone Assistant JSON mode and EU region deployment#chunk_num2',\n", + " 'release_2024#feature_Released Spark-Pinecone connector v1.2.0#chunk_num3',\n", + " 'release_2024#feature_New integration with HoneyHive#chunk_num4',\n", + " 'release_2024#feature_Released Python SDK v5.4.2#chunk_num5',\n", + " 'release_2024#feature_Launch week: Pinecone Local#chunk_num6',\n", + " 'release_2024#feature_Launch week: Enhanced security and access controls#chunk_num7',\n", + " 'release_2024#feature_Launch week: `pinecone-rerank-v0` and `cohere-rerank-3.5` on Pinecone Inference#chunk_num8',\n", + " 'release_2024#feature_Launch week: Integrated Inference#chunk_num9',\n", + " 'release_2024#feature_Released .NET SDK v2.1.0#chunk_num10',\n", + " 'release_2024#feature_Improved batch deletion guidance#chunk_num11',\n", + " 'release_2024#feature_Launch week: Released `pinecone-sparse-english-v0`#chunk_num12',\n", + " 'release_2024#feature_na#chunk_num13',\n", + " 'release_2024#feature_Pinecone docs: New workflows and best practices#chunk_num14',\n", + " 'release_2024#feature_Released Java SDK v3.1.0#chunk_num15',\n", + " 'release_2024#feature_Pinecone Assistant: Context snippets and structured data files#chunk_num16',\n", + " 'release_2024#feature_Monthly spend alerts#chunk_num17',\n", + " 'release_2024#feature_Released .NET SDK v2.0.0#chunk_num18',\n", + " 'release_2024#feature_Released Python SDK v5.4.0 and v5.4.1#chunk_num19',\n", + " 'release_2024#feature_Enabled CSV export of usage and costs#chunk_num20',\n", + " 'release_2024#feature_Added Support chat in the console#chunk_num21',\n", + " 'release_2024#feature_Published Assistant quickstart guide#chunk_num22',\n", + " 'release_2024#feature_na#chunk_num23',\n", + " 'release_2024#feature_Cequence released updated Scala SDK#chunk_num24',\n", + " 'release_2024#feature_Added index tagging for categorization#chunk_num25',\n", + " 'release_2024#feature_Released major SDK updates: Node.js, Go, Java, and Python#chunk_num26',\n", + " 'release_2024#feature_Pinecone API version `2024-10` is now the latest stable version#chunk_num27',\n", + " 'release_2024#feature_Pinecone Inference now available on the free Starter plan#chunk_num28',\n", + " 'release_2024#feature_Customer-managed encryption keys (CMEK) in early access#chunk_num29',\n", + " 'release_2024#feature_Serverless index monitoring generally available#chunk_num30',\n", + " 'release_2024#feature_Data import from Amazon S3 in public preview#chunk_num31',\n", + " 'release_2024#feature_Chat and update features added to Assistant#chunk_num32',\n", + " 'release_2024#feature_na#chunk_num33',\n", + " 'release_2024#feature_na#chunk_num34',\n", + " 'release_2024#feature_na#chunk_num35',\n", + " 'release_2024#feature_na#chunk_num36',\n", + " 'release_2024#feature_na#chunk_num37',\n", + " 'release_2024#feature_na#chunk_num38',\n", + " 'release_2024#feature_na#chunk_num39',\n", + " 'release_2024#feature_na#chunk_num40',\n", + " 'release_2024#feature_na#chunk_num41',\n", + " 'release_2025#feature_na#chunk_num0',\n", + " 'release_2025#feature_Released Java SDK v5.1.0#chunk_num1',\n", + " 'release_2025#feature_Released Node.js SDK v6.1.0#chunk_num2',\n", + " 'release_2025#feature_na#chunk_num3',\n", + " 'release_2025#feature_Released Python SDK v7.0.1 and v7.0.2#chunk_num4',\n", + " 'release_2025#feature_Released Node.s SDK v6.0.1#chunk_num5',\n", + " 'release_2025#feature_Pinecone API version `2025-04` is now the latest stable version#chunk_num6',\n", + " 'release_2025#feature_Released Python SDK v7.0.0#chunk_num7',\n", + " 'release_2025#feature_Released Node.js SDK v6.0.0#chunk_num8',\n", + " 'release_2025#feature_Released Java SDK v5.0.0#chunk_num9',\n", + " 'release_2025#feature_Released .NET SDK v4.0.0#chunk_num10',\n", + " 'release_2025#feature_New Docs IA#chunk_num11',\n", + " 'release_2025#feature_na#chunk_num12',\n", + " 'release_2025#feature_Bring Your Own Cloud (BYOC) in GCP#chunk_num13',\n", + " 'release_2025#feature_Integrate AI agents with Pinecone MCP#chunk_num14',\n", + " 'release_2025#feature_Add context to AI agents with Assistant MCP#chunk_num15',\n", + " 'release_2025#feature_Upload a file from an in-memory binary stream#chunk_num16',\n", + " 'release_2025#feature_Released Pinecone Terraform Provider v1.0.0#chunk_num17',\n", + " 'release_2025#feature_Released .NET SDK v3.1.0#chunk_num18',\n", + " 'release_2025#feature_LLM shortcuts for Pinecone docs#chunk_num19',\n", + " 'release_2025#feature_na#chunk_num20',\n", + " 'release_2025#feature_Control the context snippets the assistant sends to the LLM#chunk_num21',\n", + " 'release_2025#feature_Released Go SDK v3.1.0#chunk_num22',\n", + " 'release_2025#feature_Launch week: Dark mode#chunk_num23',\n", + " 'release_2025#feature_Launch week: Self-service audit logs#chunk_num24',\n", + " 'release_2025#feature_Launch week: Introducing the Admin API and service accounts#chunk_num25',\n", + " 'release_2025#feature_Launch week: Back up an index through the API#chunk_num26',\n", + " 'release_2025#feature_Launch week: Optimized database architecture#chunk_num27',\n", + " 'release_2025#feature_Firebase Genkit integration#chunk_num28',\n", + " 'release_2025#feature_Bring Your Own Cloud (BYOC) in public preview#chunk_num29',\n", + " 'release_2025#feature_na#chunk_num30',\n", + " 'release_2025#feature_Docs site refresh#chunk_num31',\n", + " 'release_2025#feature_Limit the number of chunks retrieved#chunk_num32',\n", + " 'release_2025#feature_Assistant Quickstart colab notebook#chunk_num33',\n", + " 'release_2025#feature_Released Node.js SDK v5.0.0#chunk_num34',\n", + " 'release_2025#feature_New integrations#chunk_num35',\n", + " 'release_2025#feature_Citation highlights in assistant responses#chunk_num36',\n", + " 'release_2025#feature_Pinecone API version `2025-01` is now the latest stable version#chunk_num37',\n", + " 'release_2025#feature_Released Python SDK v6.0.0#chunk_num38',\n", + " 'release_2025#feature_Released Java SDK v4.0.0#chunk_num39',\n", + " 'release_2025#feature_Released Go SDK v3.0.0#chunk_num40',\n", + " 'release_2025#feature_Released .NET SDK v3.0.0#chunk_num41',\n", + " 'release_2025#feature_na#chunk_num42',\n", + " 'release_2025#feature_Update to the API keys page#chunk_num43',\n", + " 'release_2025#feature_Sparse-only indexes in early access#chunk_num44',\n", + " 'release_2025#feature_Released Node SDK v4.1.0#chunk_num45',\n", + " 'release_2025#feature_New Billing Admin user role#chunk_num46',\n", + " 'release_2025#feature_Released Go SDK v2.2.0#chunk_num47']" ] - }, + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "from langchain_openai import OpenAIEmbeddings\n", + "from langchain_pinecone import PineconeVectorStore\n", + "\n", + "embeddings = OpenAIEmbeddings(api_key=OPENAI_API_KEY, model=\"text-embedding-3-small\")\n", + "\n", + "vector_store = PineconeVectorStore(index=index, embedding=embeddings)\n", + "\n", + "\n", + "# do url_title, chunk_num to enable subscriptable hashing and replacement\n", + "\n", + "def clean_url_for_title(url):\n", + " # grabs the end of the url minus .md\n", + " return url.split(\"/\")[-1].replace(\".md\", \"\")\n", + "\n", + "# Here, we follow a schema that puts the document name, and the chunk number together, like doc1#chunk1\n", + "\n", + "def generate_ids(doc_chunk):\n", + "\n", + " title = clean_url_for_title(doc_chunk.metadata['source'])\n", + " chunk_num = doc_chunk.metadata['chunk_num']\n", + " feature = doc_chunk.metadata['feature'] if 'feature' in doc_chunk.metadata else \"na\"\n", + " return f\"release_{title}#feature_{feature}#chunk_num{chunk_num}\"\n", + "\n", + "ids = [generate_ids(doc) for doc in pinecone_docs]\n", + "\n", + "\n", + "# To learn more, look here: https://docs.pinecone.io/guides/manage-data/manage-document-chunks\n", + "\n", + "vector_store.add_documents(documents=pinecone_docs, ids=ids)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A5dDWPGoIrd9" + }, + "source": [ + "## Bringing it all together: Using OpenAI to learn about our releases\n", + "\n", + "Finally, we'll setup an OpenAI LLM endpoint to generate responses given a user's query about our release notes!" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chat_models import init_chat_model\n", + "\n", + "llm = init_chat_model(\"gpt-4o-mini\", model_provider=\"openai\")" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "#OpenAI models will be unable to answer this due to training cutoffs in 2023-2024\n", + "\n", + "query = \"Tell me about version 7.0 of the Pinecone Python SDK\"\n", + "\n", + "retrieved_docs = vector_store.similarity_search(query, k=5)\n", + "docs_content = \"\\n\\n\".join(doc.page_content for doc in retrieved_docs)\n", + "\n", + "prompt = f'''You are an assistant that answers questions exclusively about the \n", + "Pinecone SDK release notes:\n", + "\n", + "Here's a question: {query}\n", + "\n", + "Here's some context from the release notes:\n", + "\n", + "{docs_content}\n", + "\n", + "\n", + "Question: {query}\n", + "\n", + "Answer:\n", + "'''\n", + "\n", + "# This will take a few seconds to run, due to the generation of the response from OpenAI\n", + "answer = llm.invoke(prompt)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sjOBIQ5rFeLZ" + }, + "source": [ + "We can peek at the retrieved documents to confirm up to date information is being passed in:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "vNkoIzQjjMTQ" - }, - "outputs": [], - "source": [ - "pc.delete_index(name=index_name)" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "Doc number: 1\n", + "Released [`v7.0.1`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.1) and [`v7.0.2`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.2) of the [Pinecone Python SDK](/reference/python-sdk). These versions fix minor bugs discovered since the release of the `v7.0.0` major version.\n", + " \n", + "\n", + "Metadata:\n", + "{'chunk_num': 4.0, 'feature': 'Released Python SDK v7.0.1 and v7.0.2', 'month_year': 'May 2025', 'release': '2025 releases', 'source': 'https://docs.pinecone.io/release-notes/2025.md'}\n", + "----------------------------------------------------------------------------------------------------\n", + "Doc number: 2\n", + "Released [`v7.0.1`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.1) and [`v7.0.2`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.2) of the [Pinecone Python SDK](/reference/python-sdk). These versions fix minor bugs discovered since the release of the `v7.0.0` major version.\n", + " \n", + "\n", + "Metadata:\n", + "{'chunk_num': 4.0, 'feature': 'Released Python SDK v7.0.1 and v7.0.2', 'month_year': 'May 2025', 'release': '2025 releases', 'source': 'https://docs.pinecone.io/release-notes/2025.md'}\n", + "----------------------------------------------------------------------------------------------------\n", + "Doc number: 3\n", + "Released [`v7.0.0`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.0) of the [Pinecone Python SDK](/reference/python-sdk). This version uses the latest stable API version, `2025-04`, and includes support for the following: \n", + "* [Creating and managing backups](/guides/manage-data/back-up-an-index)\n", + "* [Restoring indexes from backups](/guides/manage-data/restore-an-index)\n", + "* [Listing embedding and reranking models hosted by Pinecone](/reference/api/2025-04/inference/list_models)\n", + "* [Getting details about a model hosted by Pinecone](/reference/api/2025-04/inference/describe_model)\n", + "* [Creating a BYOC index](/guides/production/bring-your-own-cloud#create-an-index) \n", + "Additionally, the `pinecone-plugin-assistant` package required to work with [Pinecone Assistant](/guides/assistant/overview) is now included by default; it is no longer necessary to install the plugin separately.\n", + " \n", + "\n", + "Metadata:\n", + "{'chunk_num': 7.0, 'feature': 'Released Python SDK v7.0.0', 'month_year': 'May 2025', 'release': '2025 releases', 'source': 'https://docs.pinecone.io/release-notes/2025.md'}\n", + "----------------------------------------------------------------------------------------------------\n", + "Doc number: 4\n", + "Released [`v7.0.0`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.0) of the [Pinecone Python SDK](/reference/python-sdk). This version uses the latest stable API version, `2025-04`, and includes support for the following: \n", + "* [Creating and managing backups](/guides/manage-data/back-up-an-index)\n", + "* [Restoring indexes from backups](/guides/manage-data/restore-an-index)\n", + "* [Listing embedding and reranking models hosted by Pinecone](/reference/api/2025-04/inference/list_models)\n", + "* [Getting details about a model hosted by Pinecone](/reference/api/2025-04/inference/describe_model)\n", + "* [Creating a BYOC index](/guides/production/bring-your-own-cloud#create-an-index) \n", + "Additionally, the `pinecone-plugin-assistant` package required to work with [Pinecone Assistant](/guides/assistant/overview) is now included by default; it is no longer necessary to install the plugin separately.\n", + " \n", + "\n", + "Metadata:\n", + "{'chunk_num': 7.0, 'feature': 'Released Python SDK v7.0.0', 'month_year': 'May 2025', 'release': '2025 releases', 'source': 'https://docs.pinecone.io/release-notes/2025.md'}\n", + "----------------------------------------------------------------------------------------------------\n", + "Doc number: 5\n", + "Released [`v6.0.0`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v6.0.0) of the [Pinecone Python SDK](/reference/python-sdk). This version uses the latest stable API version, `2025-01`, and includes support for the following: \n", + "* [Index tags](/guides/manage-data/manage-indexes#configure-index-tags) to categorize and identify your indexes.\n", + "* [Integrated inference](/reference/api/introduction#inference) without the need for extra plugins. If you were using the preview functionality of integrated inference, you must uninstall the `pinecone-plugin-records` package to use the `v6.0.0` release.\n", + "* Enum objects to help with the discoverability of some configuration options, for example, `Metric`, `AwsRegion`, `GcpRegion`, `PodType`, `EmbedModel`, `RerankModel`. This is a backwards compatible change; you can still pass string values for affected fields.\n", + "* New client variants, `PineconeAsyncio` and `IndexAsyncio`, which provide `async` methods for use with [asyncio](https://docs.python.org/3/library/asyncio.html). This makes it possible to use Pinecone with modern async web frameworks such as [FastAPI](https://fastapi.tiangolo.com/), [Quart](https://quart.palletsprojects.com/en/latest/), and [Sanic](https://sanic.dev/en/). Async support should significantly increase the efficiency of running many upserts in parallel. \n", + "\n", + "Before upgrading to `v6.0.0`, update all relevant code to account for the following [breaking changes](/reference/api/versioning#breaking-changes). See the [`v6.0.0`](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v6.0.0) release notes for full details. \n", + "* Incorporated the `pinecone-plugin-records` and `pinecone-plugin-inference` plugins into the `pinecone` package. If you are using these plugins, you must unstall them to use `v6.0.0`.\n", + "* Dropped support for Python 3.8, which has now reached official end of life, and added support for Python 3.13.\n", + "* Removed the explicit dependency on `tqdm`, which is used to provide a progress bar when upserting data into Pinecone. If `tqdm` is available in the environment, the Pinecone SDK will detect and use it, but `tdqm` is no longer required to run the SDK. Popular notebook platforms such as [Jupyter](https://jupyter.org/) and [Google Colab](https://colab.google/) already include `tqdm` in the environment by default, but if you are running small scripts in other environments and want to continue seeing progress bars, you will need to separately install the `tqdm` package.\n", + "* Removed some previously deprecated and rarely used keyword arguments (`config`, `openapi_config`, and `index_api`) to instead prefer dedicated keyword arguments for individual settings such as `api_key`, `proxy_url`, etc.\n", + "\n", + " \n", + "\n", + "Metadata:\n", + "{'chunk_num': 38.0, 'feature': 'Released Python SDK v6.0.0', 'month_year': 'February 2025', 'release': '2025 releases', 'source': 'https://docs.pinecone.io/release-notes/2025.md'}\n", + "----------------------------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "for num, d in enumerate(retrieved_docs):\n", + " print(f\"Doc number: {num+1}\")\n", + " print(d.page_content)\n", + " print(\"Metadata:\")\n", + " print(d.metadata)\n", + " print(\"-\"*100)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Comparing responses with/without RAG" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Without our RAG pipeline with release notes indexed, OpenAI models will be\n", + "unable to answer questions about new versions of Pinecone. They may even \"hallucinate\", or fabricate information about the versions that may not exist!" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "ehJEn68qADoH" - }, - "source": [ - "---" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "As of my last update in October 2023, Pinecone frequently releases updates to enhance its features, performance, and usability. To find the most recent major feature release for the Pinecone Python SDK, I recommend checking the official Pinecone documentation or their GitHub repository. They typically have a changelog that outlines new features, improvements, and bug fixes.\n", + "\n", + "If you're looking for specific features or improvements released recently, you can always visit the Pinecone website or their community forums for announcements or summaries of the latest updates. If you have any specific functionality in mind that you're interested in, feel free to ask!\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.12.9" + ], + "source": [ + "print(llm.invoke(\"Tell about the most recent major feature release in the Pinecone Python SDK\").content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, with our pipeline in place, we get an answer that is more likely to be correct, and definitely grounded. " + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The Pinecone Python SDK version 7.0 includes a major release (`v7.0.0`) and subsequent minor updates (`v7.0.1` and `v7.0.2`) that address minor bugs.\n", + "\n", + "### Version 7.0.0\n", + "Released on May 19, 2025, this version utilizes the latest stable API version, `2025-04`, and offers several new features:\n", + "- **Creating and managing backups**: Users can now create and manage backups of their indexes.\n", + "- **Restoring indexes from backups**: This feature allows users to restore their indexes from previously created backups.\n", + "- **Listing embedding and reranking models**: Users can list models that are hosted by Pinecone.\n", + "- **Getting model details**: This feature provides detailed information about a specific model hosted by Pinecone.\n", + "- **Creating a BYOC (Bring Your Own Cloud) index**: Users are now able to create indexes within their own cloud environments.\n", + "\n", + "Additionally, the `pinecone-plugin-assistant` package, which is needed for working with Pinecone Assistant, is now included by default, eliminating the need for a separate installation.\n", + "\n", + "### Minor Versions: 7.0.1 and 7.0.2\n", + "Released on May 29, 2025, versions `7.0.1` and `7.0.2` were released to fix minor bugs that had been discovered after the `v7.0.0` major release.\n", + "\n", + "For more details, you can view the release notes for each version: \n", + "- [v7.0.0](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.0)\n", + "- [v7.0.1](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.1)\n", + "- [v7.0.2](https://github.com/pinecone-io/pinecone-python-client/releases/tag/v7.0.2)\n" + ] } + ], + "source": [ + "print(answer.content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Wrapping up\n", + "\n", + "And that's that! You've successfully implemented retrieval augmented generation with Pinecone, OpenAI and LangChain. Wanna learn more? Try implementing the following:\n", + "\n", + "- Sparse search to enable precise time, date and feature recognition in query results\n", + "- Expanding the set of documents to encompass all Pinecone documentaiotn\n", + "- Learning how to chunk and process code data, to build your own code assistant\n", + "\n", + "To finish, let's delete our index:" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "metadata": { + "id": "PpJp-xExFeLa" + }, + "outputs": [], + "source": [ + "pc.delete_index(name=index_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2kNh44bEFeLe" + }, + "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.9" }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file + "vscode": { + "interpreter": { + "hash": "57376684f67c5d7b1589c855d7d0f1a1bdf8944ab1b903e711fdbf39434567bb" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}