diff --git a/learn/generation/langchain/handbook/02-langchain-chains.ipynb b/learn/generation/langchain/handbook/02-langchain-chains.ipynb index 6bf58fe0..e870c2b7 100644 --- a/learn/generation/langchain/handbook/02-langchain-chains.ipynb +++ b/learn/generation/langchain/handbook/02-langchain-chains.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "uZR3iGJJtdDE", "metadata": { "colab": { @@ -11,9 +11,19 @@ "id": "uZR3iGJJtdDE", "outputId": "9ebb9f66-add2-4567-e37e-05323073e26b" }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "[notice] A new release of pip is available: 23.1.2 -> 25.1.1\n", + "[notice] To update, run: python.exe -m pip install --upgrade pip\n" + ] + } + ], "source": [ - "!pip install -qU langchain openai " + "!pip install -qU langchain openai langchain-community numexpr" ] }, { @@ -37,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "66fb9c2a", "metadata": { "id": "66fb9c2a" @@ -48,9 +58,11 @@ "import re\n", "\n", "from getpass import getpass\n", - "from langchain import OpenAI, PromptTemplate\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain import PromptTemplate\n", "from langchain.chains import LLMChain, LLMMathChain, TransformChain, SequentialChain\n", - "from langchain.callbacks import get_openai_callback" + "from langchain.callbacks import get_openai_callback\n", + "from langchain_core.runnables import RunnableLambda, RunnableParallel, RunnablePassthrough" ] }, { @@ -65,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "v86cmyppxdfc", "metadata": { "colab": { @@ -76,20 +88,27 @@ }, "outputs": [], "source": [ - "OPENAI_API_KEY = getpass()" + "import os\n", + "from getpass import getpass\n", + "\n", + "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") \\\n", + " or getpass(\"Enter your OpenAI API key: \")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "baaa74b8", "metadata": {}, "outputs": [], "source": [ - "llm = OpenAI(\n", - " temperature=0, \n", - " openai_api_key=OPENAI_API_KEY\n", - " )" + "\n", + "\n", + "# initialize the models\n", + "llm = ChatOpenAI(\n", + " model_name=\"gpt-3.5-turbo\", # or \"gpt-4\" or other available models\n", + " temperature=0.7\n", + ")" ] }, { @@ -104,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "DsC3szr6yP3L", "metadata": { "id": "DsC3szr6yP3L" @@ -113,7 +132,7 @@ "source": [ "def count_tokens(chain, query):\n", " with get_openai_callback() as cb:\n", - " result = chain.run(query)\n", + " result = chain.invoke(query)\n", " print(f'Spent a total of {cb.total_tokens} tokens')\n", "\n", " return result" @@ -127,84 +146,30 @@ "id": "6e1f31b4" }, "source": [ - "## What are chains anyway?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "5b919c3a", - "metadata": { - "id": "5b919c3a" - }, - "source": [ - "**Definition**: Chains are one of the fundamental building blocks of this lib (as you can guess!).\n", + "## What are chains anyway?\n", "\n", - "The official definition of chains is the following:\n", + "Chains in LangChain are now built using the LangChain Expression Language (LCEL), which takes a declarative approach to combining components. Instead of using predefined chain classes, LCEL lets you compose chains using the `|` operator and other composition primitives.\n", "\n", + "### Types of Chain Composition\n", "\n", - "> A chain is made up of links, which can be either primitives or other chains. Primitives can be either prompts, llms, utils, or other chains.\n", + "1. **Sequential Chains** (`|` operator)\n", + " - Chain components one after another\n", + " - Example: `prompt | llm | output_parser`\n", "\n", + "2. **Parallel Chains** (`RunnableParallel`)\n", + " - Run multiple operations concurrently\n", + " - Example: Running multiple prompts or retrievers in parallel\n", "\n", - "So a chain is basically a pipeline that processes an input by using a specific combination of primitives. Intuitively, it can be thought of as a 'step' that performs a certain set of operations on an input and returns the result. They can be anything from a prompt-based pass through a LLM to applying a Python function to an text." - ] - }, - { - "cell_type": "markdown", - "id": "c4644b2f", - "metadata": { - "id": "c4644b2f" - }, - "source": [ - "Chains are divided in three types: Utility chains, Generic chains and Combine Documents chains. In this edition, we will focus on the first two since the third is too specific (will be covered in due course).\n", + "3. **Complex Workflows**\n", + " - For more complex scenarios involving branching, cycles, or multiple agents\n", + " - Recommended to use LangGraph instead of LCEL directly\n", "\n", - "1. Utility Chains: chains that are usually used to extract a specific answer from a llm with a very narrow purpose and are ready to be used out of the box.\n", - "2. Generic Chains: chains that are used as building blocks for other chains but cannot be used out of the box on their own." - ] - }, - { - "cell_type": "markdown", - "id": "e4d283b6", - "metadata": { - "id": "e4d283b6" - }, - "source": [ - "Let's take a peek into what these chains have to offer!" - ] - }, - { - "cell_type": "markdown", - "id": "831827b7", - "metadata": { - "id": "831827b7" - }, - "source": [ - "### Utility Chains" - ] - }, - { - "cell_type": "markdown", - "id": "6c66e4b4", - "metadata": { - "id": "6c66e4b4" - }, - "source": [ - "Let's start with a simple utility chain. The `LLMMathChain` gives llms the ability to do math. Let's see how it works!" - ] - }, - { - "cell_type": "markdown", - "id": "HF3XCWD2sVi0", - "metadata": { - "id": "HF3XCWD2sVi0" - }, - "source": [ - "#### Pro-tip: use `verbose=True` to see what the different steps in the chain are!" + "Let's start with a simple example: creating a sequential math chain that can handle calculations..." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 6, "id": "b4161561", "metadata": { "colab": { @@ -218,272 +183,155 @@ "name": "stdout", "output_type": "stream", "text": [ - "\n", - "\n", - "\u001b[1m> Entering new LLMMathChain chain...\u001b[0m\n", - "What is 13 raised to the .3432 power?\u001b[32;1m\u001b[1;3m\n", - "```python\n", - "import math\n", - "print(math.pow(13, .3432))\n", - "```\n", - "\u001b[0m\n", - "Answer: \u001b[33;1m\u001b[1;3m2.4116004626599237\n", - "\u001b[0m\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "Spent a total of 272 tokens\n" + "The result is: 2.4116004626599237\n" ] - }, - { - "data": { - "text/plain": [ - "'Answer: 2.4116004626599237\\n'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "llm_math = LLMMathChain(llm=llm, verbose=True)\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "from langchain_core.runnables import RunnableLambda\n", + "import numexpr\n", "\n", - "count_tokens(llm_math, \"What is 13 raised to the .3432 power?\")" - ] - }, - { - "cell_type": "markdown", - "id": "198eebb2", - "metadata": { - "id": "198eebb2" - }, - "source": [ - "Let's see what is going on here. The chain recieved a question in natural language and sent it to the llm. The llm returned a Python code which the chain compiled to give us an answer. A few questions arise.. How did the llm know that we wanted it to return Python code? " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "a7a0821a", - "metadata": { - "id": "a7a0821a" - }, - "source": [ - "**Enter prompts**" + "# Create a function to handle calculations\n", + "def calculate(expression: str) -> str:\n", + " \"\"\"Calculate using numexpr, with support for basic math operations.\"\"\"\n", + " try:\n", + " result = float(numexpr.evaluate(expression))\n", + " return f\"The result is: {result}\"\n", + " except Exception as e:\n", + " return f\"Error in calculation: {str(e)}\"\n", + "\n", + "# Create the prompt\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful math assistant. When given a math problem, respond ONLY with the mathematical expression that would solve it. For example, if asked 'What is 2 raised to the 3rd power?', respond only with '2**3'.\"),\n", + " (\"user\", \"{question}\")\n", + "])\n", + "\n", + "# Wrap our calculation function with RunnableLambda for explicit LCEL pattern\n", + "calculate_runnable = RunnableLambda(calculate)\n", + "\n", + "# Create the chain using LCEL with explicit RunnableLambda\n", + "math_chain = (\n", + " prompt \n", + " | ChatOpenAI(temperature=0) \n", + " | StrOutputParser() # Convert to string\n", + " | calculate_runnable # Our calculation function wrapped in RunnableLambda\n", + ")\n", + "\n", + "# Use the chain with our example\n", + "response = math_chain.invoke({\n", + " \"question\": \"What is 13 raised to the .3432 power?\"\n", + "})\n", + "print(response)" ] }, { "cell_type": "markdown", - "id": "c86c5798", - "metadata": { - "id": "c86c5798" - }, + "id": "86fecbca", + "metadata": {}, "source": [ - "The question we send as input to the chain is not the only input that the llm recieves 😉. The input is inserted into a wider context, which gives precise instructions on how to interpret the input we send. This is called a _prompt_. Let's see what this chain's prompt is!" + "Let's see what is going on here. The chain processes our input through several sequential steps:\n", + "\n", + "1. The prompt template formats our question\n", + "2. The LLM converts it to a mathematical expression\n", + "3. The StrOutputParser ensures we get a clean string\n", + "4. Finally, our calculate function computes the result\n", + "\n", + "But how did the LLM know to return just the mathematical expression? 🤔\n", + "\n", + "**Enter prompts**\n", + "\n", + "The question we send isn't the only input the LLM receives 😉. Look at our prompt template:\n" ] }, { "cell_type": "code", - "execution_count": 34, - "id": "62778ef4", - "metadata": { - "id": "62778ef4", - "outputId": "211670a8-db56-4f68-d873-97d279870890" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "You are GPT-3, and you can't do math.\n", - "\n", - "You can do basic math, and your memorization abilities are impressive, but you can't do any complex calculations that a human could not do in their head. You also have an annoying tendency to just make up highly specific, but wrong, answers.\n", - "\n", - "So we hooked you up to a Python 3 kernel, and now you can execute code. If anyone gives you a hard math problem, just use this format and we’ll take care of the rest:\n", - "\n", - "Question: ${{Question with hard calculation.}}\n", - "```python\n", - "${{Code that prints what you need to know}}\n", - "```\n", - "```output\n", - "${{Output of your code}}\n", - "```\n", - "Answer: ${{Answer}}\n", - "\n", - "Otherwise, use this simpler format:\n", - "\n", - "Question: ${{Question without hard calculation}}\n", - "Answer: ${{Answer}}\n", - "\n", - "Begin.\n", - "\n", - "Question: What is 37593 * 67?\n", - "\n", - "```python\n", - "print(37593 * 67)\n", - "```\n", - "```output\n", - "2518731\n", - "```\n", - "Answer: 2518731\n", - "\n", - "Question: {question}\n", - "\n" - ] - } - ], + "execution_count": 7, + "id": "42224b54", + "metadata": {}, + "outputs": [], "source": [ - "print(llm_math.prompt.template)" + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful math assistant. When given a math problem, respond ONLY with the mathematical expression that would solve it. For example, if asked 'What is 2 raised to the 3rd power?', respond only with '2**3'.\"),\n", + " (\"user\", \"{question}\")\n", + "])" ] }, { "cell_type": "markdown", - "id": "708031d8", - "metadata": { - "id": "708031d8" - }, + "id": "abdb8561", + "metadata": {}, "source": [ - "Ok.. let's see what we got here. So, we are literally telling the llm that for complex math problems **it should not try to do math on its own** but rather it should print a Python code that will calculate the math problem instead. Probably, if we just sent the query without any context, the llm would try (and fail) to calculate this on its own. Wait! This is testable.. let's try it out! 🧐" + "The system message explicitly instructs the LLM to return only the mathematical expression. Without this context, the LLM would try to calculate the result itself. Let's test this by trying without the system message:\n" ] }, { "cell_type": "code", - "execution_count": 35, - "id": "66b92768", - "metadata": { - "id": "66b92768", - "outputId": "6c9b7f59-529d-409e-8562-5a622f326473" - }, + "execution_count": 8, + "id": "8e477bc6", + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Spent a total of 17 tokens\n" + "13^0.3432 is approximately equal to 2.732.\n" ] - }, - { - "data": { - "text/plain": [ - "'\\n\\n2.907'" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "# we set the prompt to only have the question we ask\n", - "prompt = PromptTemplate(input_variables=['question'], template='{question}')\n", - "llm_chain = LLMChain(prompt=prompt, llm=llm)\n", + "# Simple prompt without guidance\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"user\", \"{question}\")\n", + "])\n", "\n", - "# we ask the llm for the answer with no context\n", + "basic_chain = (\n", + " prompt \n", + " | ChatOpenAI(temperature=0)\n", + " | StrOutputParser()\n", + ")\n", "\n", - "count_tokens(llm_chain, \"What is 13 raised to the .3432 power?\")" + "response = basic_chain.invoke({\n", + " \"question\": \"What is 13 raised to the .3432 power?\"\n", + "})\n", + "print(response) # The LLM tries to calculate it directly and gets it wrong!\n" ] }, { "cell_type": "markdown", - "id": "d147e7bf", - "metadata": { - "id": "d147e7bf" - }, + "id": "56da4f48", + "metadata": {}, "source": [ - "Wrong answer! Herein lies the power of prompting and one of our most important insights so far: \n", + "This demonstrates the power of prompting in LCEL: by carefully designing our prompts, we can guide the LLM's behavior precisely.\n", "\n", - "**Insight**: _by using prompts intelligently, we can force the llm to avoid common pitfalls by explicitly and purposefully programming it to behave in a certain way._" - ] - }, - { - "cell_type": "markdown", - "id": "1cd2a31f", - "metadata": { - "id": "1cd2a31f" - }, - "source": [ - "Another interesting point about this chain is that it not only runs an input through the llm but it later compiles Python code. Let's see exactly how this works." + "The beauty of LCEL's sequential composition is how clearly we can see each step in the chain:\n" ] }, { "cell_type": "code", - "execution_count": 36, - "id": "3488c5b6", - "metadata": { - "id": "3488c5b6", - "outputId": "8b32a998-8e11-48bf-f21c-f5d086186508" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:\n", - " llm_executor = LLMChain(prompt=self.prompt, llm=self.llm)\n", - " python_executor = PythonREPL()\n", - " self.callback_manager.on_text(inputs[self.input_key], verbose=self.verbose)\n", - " t = llm_executor.predict(question=inputs[self.input_key], stop=[\"```output\"])\n", - " self.callback_manager.on_text(t, color=\"green\", verbose=self.verbose)\n", - " t = t.strip()\n", - " if t.startswith(\"```python\"):\n", - " code = t[9:-4]\n", - " output = python_executor.run(code)\n", - " self.callback_manager.on_text(\"\\nAnswer: \", verbose=self.verbose)\n", - " self.callback_manager.on_text(output, color=\"yellow\", verbose=self.verbose)\n", - " answer = \"Answer: \" + output\n", - " elif t.startswith(\"Answer:\"):\n", - " answer = t\n", - " else:\n", - " raise ValueError(f\"unknown format from LLM: {t}\")\n", - " return {self.output_key: answer}\n", - "\n" - ] - } - ], - "source": [ - "print(inspect.getsource(llm_math._call))" - ] - }, - { - "cell_type": "markdown", - "id": "fa6b6c2e", - "metadata": { - "id": "fa6b6c2e" - }, - "source": [ - "So we can see here that if the llm returns Python code we will compile it with a Python REPL* simulator. We now have the full picture of the chain: either the llm returns an answer (for simple math problems) or it returns Python code which we compile for an exact answer to harder problems. Smart!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "67f96bd3", - "metadata": { - "id": "67f96bd3" - }, + "execution_count": 9, + "id": "0fb5f537", + "metadata": {}, + "outputs": [], "source": [ - "Also notice that here we get our first example of **chain composition**, a key concept behind what makes langchain special. We are using the `LLMMathChain` which in turn initializes and uses an `LLMChain` (a 'Generic Chain') when called. We can make any arbitrary number of such compositions, effectively 'chaining' many such chains to achieve highly complex and customizable behaviour." + "math_chain = (\n", + " prompt # Step 1: Format the input with our system message\n", + " | ChatOpenAI(temperature=0) # Step 2: Get mathematical expression from LLM\n", + " | StrOutputParser() # Step 3: Convert to clean string\n", + " | calculate # Step 4: Evaluate the expression\n", + ")" ] }, { "cell_type": "markdown", - "id": "b109619a", - "metadata": { - "id": "b109619a" - }, + "id": "9b4ea2a2", + "metadata": {}, "source": [ - "Utility chains usually follow this same basic structure: there is a prompt for constraining the llm to return a very specific type of response from a given query. We can ask the llm to create SQL queries, API calls and even create Bash commands on the fly 🔥\n", + "Each step flows naturally into the next using the `|` operator, making it easy to understand and modify the chain's behavior. This is much more flexible than the old approach of using predefined chain classes - we can easily add, remove, or modify steps as needed!\n", "\n", - "The list continues to grow as langchain becomes more and more flexible and powerful so we encourage you to [check it out](https://langchain.readthedocs.io/en/latest/modules/chains/utility_how_to.html) and tinker with the example notebooks that you might find interesting." - ] - }, - { - "cell_type": "markdown", - "id": "381e329c", - "metadata": { - "id": "381e329c" - }, - "source": [ - "*_A Python REPL (Read-Eval-Print Loop) is an interactive shell for executing Python code line by line_" + "*_Note: The `calculate` function uses `numexpr` to safely evaluate mathematical expressions without needing a full Python REPL (Read-Eval-Print Loop)._" ] }, { @@ -494,223 +342,90 @@ "id": "f66a25a2" }, "source": [ - "### Generic chains" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "70b32a84", - "metadata": { - "id": "70b32a84" - }, - "source": [ - "There are only three Generic Chains in langchain and we will go all in to showcase them all in the same example. Let's go!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "4b8e2048", - "metadata": { - "id": "4b8e2048" - }, - "source": [ - "Say we have had experience of getting dirty input texts. Specifically, as we know, llms charge us by the number of tokens we use and we are not happy to pay extra when the input has extra characters. Plus its not neat 😉" - ] - }, - { - "cell_type": "markdown", - "id": "a6e778d2", - "metadata": { - "id": "a6e778d2" - }, - "source": [ - "First, we will build a custom transform function to clean the spacing of our texts. We will then use this function to build a chain where we input our text and we expect a clean text as output." + "### Building Complex Chains with LCEL\n", + "\n", + "Let's build a more complex example that shows how to combine different components using LCEL. We'll create a chain that cleans up messy text and then paraphrases it in a specific style.\n", + "\n", + "First, let's create a function to clean up text by removing extra spaces and newlines. In LCEL, we can use regular functions directly in our chain:" ] }, { "cell_type": "code", - "execution_count": 37, - "id": "c794e00a", - "metadata": { - "id": "c794e00a" - }, + "execution_count": 10, + "id": "41d95063", + "metadata": {}, "outputs": [], "source": [ - "def transform_func(inputs: dict) -> dict:\n", - " text = inputs[\"text\"]\n", - " \n", + "def clean_text(text: str) -> str:\n", " # replace multiple new lines and multiple spaces with a single one\n", " text = re.sub(r'(\\r\\n|\\r|\\n){2,}', r'\\n', text)\n", " text = re.sub(r'[ \\t]+', ' ', text)\n", - "\n", - " return {\"output_text\": text}" - ] - }, - { - "cell_type": "markdown", - "id": "42dc1ac6", - "metadata": { - "id": "42dc1ac6" - }, - "source": [ - "Importantly, when we initialize the chain we do not send an llm as an argument. As you can imagine, not having an llm makes this chain's abilities much weaker than the example we saw earlier. However, as we will see next, combining this chain with other chains can give us highly desirable results." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "286f7295", - "metadata": { - "id": "286f7295" - }, - "outputs": [], - "source": [ - "clean_extra_spaces_chain = TransformChain(input_variables=[\"text\"], output_variables=[\"output_text\"], transform=transform_func)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "977bf11a", - "metadata": { - "id": "977bf11a", - "outputId": "8d6eaa5e-b417-4c17-a345-7b7e32071430" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'A random text with some irregular spacing.\\n Another one here as well.'" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "clean_extra_spaces_chain.run('A random text with some irregular spacing.\\n\\n\\n Another one here as well.')" - ] - }, - { - "cell_type": "markdown", - "id": "b3f84cd0", - "metadata": { - "id": "b3f84cd0" - }, - "source": [ - "Great! Now things will get interesting.\n", - "\n", - "Say we want to use our chain to clean an input text and then paraphrase the input in a specific style, say a poet or a policeman. As we now know, the `TransformChain` does not use a llm so the styling will have to be done elsewhere. That's where our `LLMChain` comes in. We know about this chain already and we know that we can do cool things with smart prompting so let's take a chance!" + " return text" ] }, { "cell_type": "markdown", - "id": "5b77042a", - "metadata": { - "id": "5b77042a" - }, + "id": "98ca3a11", + "metadata": {}, "source": [ - "First we will build the prompt template:" + "Now, let's create our prompt template for the paraphrasing:" ] }, { "cell_type": "code", - "execution_count": 40, - "id": "73719a5d", - "metadata": { - "id": "73719a5d" - }, + "execution_count": 11, + "id": "71a5596e", + "metadata": {}, "outputs": [], "source": [ - "template = \"\"\"Paraphrase this text:\n", - "\n", - "{output_text}\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a creative writing assistant.\"),\n", + " (\"user\", \"\"\"Please paraphrase this text in the style of {style}:\n", "\n", - "In the style of a {style}.\n", - "\n", - "Paraphrase: \"\"\"\n", - "prompt = PromptTemplate(input_variables=[\"style\", \"output_text\"], template=template)" + "{text}\"\"\")\n", + "])" ] }, { "cell_type": "markdown", - "id": "83b2ec83", - "metadata": { - "id": "83b2ec83" - }, + "id": "9f5ff6c9", + "metadata": {}, "source": [ - "And next, initialize our chain:" + "Now we can combine everything into a sequential chain using LCEL's `|` operator. The beauty of LCEL is how naturally we can compose these components:\n" ] }, { "cell_type": "code", - "execution_count": 41, - "id": "48a067ab", - "metadata": { - "id": "48a067ab" - }, - "outputs": [], - "source": [ - "style_paraphrase_chain = LLMChain(llm=llm, prompt=prompt, output_key='final_output')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "2324005d", - "metadata": { - "id": "2324005d" - }, + "execution_count": 12, + "id": "268da3a9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Yo, check it, chains in the mix\n", + "Bringin' components together, that's the fix\n", + "Makin' applications smooth and tight\n", + "User input, PromptTemplate, LLM, outta sight\n", + "Linkin' chains for a complex ride\n", + "Mix 'em up, other components by their side\n" + ] + } + ], "source": [ - "Great! Notice that the input text in the template is called 'output_text'. Can you guess why?\n", + "# Create the chain using LCEL\n", + "style_chain = (\n", + " {\n", + " \"text\": lambda x: clean_text(x[\"text\"]), # Extract and clean the text from input dict\n", + " \"style\": lambda x: x[\"style\"] # Extract style from input dict\n", + " }\n", + " | prompt # Format with our template\n", + " | ChatOpenAI(temperature=0.7) # Generate creative paraphrase\n", + " | StrOutputParser() # Convert to string\n", + ")\n", "\n", - "We are going to pass the output of the `TransformChain` to the `LLMChain`!" - ] - }, - { - "cell_type": "markdown", - "id": "c5da4925", - "metadata": { - "id": "c5da4925" - }, - "source": [ - "Finally, we need to combine them both to work as one integrated chain. For that we will use `SequentialChain` which is our third generic chain building block." - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "06f51f17", - "metadata": { - "id": "06f51f17" - }, - "outputs": [], - "source": [ - "sequential_chain = SequentialChain(chains=[clean_extra_spaces_chain, style_paraphrase_chain], input_variables=['text', 'style'], output_variables=['final_output'])" - ] - }, - { - "cell_type": "markdown", - "id": "7f0f51d8", - "metadata": { - "id": "7f0f51d8" - }, - "source": [ - "Our input is the langchain docs description of what chains are but dirty with some extra spaces all around." - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "a8032489", - "metadata": { - "id": "a8032489" - }, - "outputs": [], - "source": [ + "# Our input text with messy spacing\n", "input_text = \"\"\"\n", "Chains allow us to combine multiple \n", "\n", @@ -723,170 +438,144 @@ "\n", "\n", "combining chains with other components.\n", - "\"\"\"" + "\"\"\"\n", + "\n", + "# Run the chain\n", + "response = style_chain.invoke({\n", + " \"text\": input_text,\n", + " \"style\": \"a 90s rapper\"\n", + "})\n", + "print(response)" ] }, { "cell_type": "markdown", - "id": "b2f55d21", - "metadata": { - "id": "b2f55d21" - }, - "source": [ - "We are all set. Time to get creative!" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "d507aa5c", + "id": "0b1f98f8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Spent a total of 163 tokens\n" - ] - }, - { - "data": { - "text/plain": [ - "\"\\nChains let us link up multiple pieces to make one dope app. Like, we can take user input, style it up with a PromptTemplate, then pass it to an LLM. We can get even more creative by combining multiple chains or mixin' chains with other components.\"" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "count_tokens(sequential_chain, {'text': input_text, 'style': 'a 90s rapper'})" - ] - }, - { - "cell_type": "markdown", - "id": "60b52e19", - "metadata": { - "id": "60b52e19" - }, - "source": [ - "## A note on langchain-hub" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "02f649da", - "metadata": { - "id": "02f649da" - }, - "source": [ - "`langchain-hub` is a sister library to `langchain`, where all the chains, agents and prompts are serialized for us to use." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "411500c2", - "metadata": { - "id": "411500c2" - }, - "outputs": [], - "source": [ - "from langchain.chains import load_chain" - ] - }, - { - "cell_type": "markdown", - "id": "b375e5b7", - "metadata": { - "id": "b375e5b7" - }, "source": [ - "Loading from langchain hub is as easy as finding the chain you want to load in the repository and then using `load_chain` with the corresponding path. We also have `load_prompt` and `initialize_agent`, but more on that later. Let's see how we can do this with our `LLMMathChain` we saw earlier:" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "fbe8748d", - "metadata": { - "id": "fbe8748d" - }, - "outputs": [], - "source": [ - "llm_math_chain = load_chain('lc://chains/llm-math/chain.json')" + "Let's look at how this chain works:\n", + "\n", + "1. The dictionary `{\"text\": clean_text, \"style\": lambda x: x}` processes our inputs in parallel using `RunnableParallel`\n", + "2. The `|` operator connects each component, showing the clear flow of data\n", + "3. Each step in the chain serves a specific purpose and is easily modifiable\n", + "4. The components work together seamlessly to process and transform the text\n", + "\n", + "This demonstrates how LCEL lets us compose simple components into powerful chains while keeping the code readable and maintainable. Whether you're processing text, generating content, or building complex workflows, LCEL's composition primitives make it easy to build exactly what you need! 🔥" ] }, { "cell_type": "markdown", - "id": "ebcfe67c", - "metadata": { - "id": "ebcfe67c" - }, + "id": "bd8fb6aa", + "metadata": {}, "source": [ - "What if we want to change some of the configuration parameters? We can simply override it after loading:" + "### Using RunnableParallel and RunnablePassthrough\n", + "\n", + "Let's explore how to use `RunnableParallel` for running multiple operations concurrently and `RunnablePassthrough` for passing data through unchanged:" ] }, { "cell_type": "code", - "execution_count": 52, - "id": "d0d54233", - "metadata": { - "id": "d0d54233", - "outputId": "92eba1cf-e47b-4df1-cc51-caee5a6a720b" - }, + "execution_count": 13, + "id": "6983ae77", + "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "Sentiment: The sentiment of the statement is positive. The use of words like \"exceeded my expectations\" and \"great quality\" indicates a high level of satisfaction and positivity towards the product.\n", + "Summary: The product surpassed expectations with its excellent quality.\n", + "Original: The product exceeded my expectations. Great quality!\n" + ] } ], "source": [ - "llm_math_chain.verbose" + "from langchain_core.runnables import RunnableParallel, RunnablePassthrough\n", + "\n", + "# Create two different analysis prompts\n", + "sentiment_prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a sentiment analysis expert. Analyze the emotional tone.\"),\n", + " (\"user\", \"What's the sentiment of: {text}\")\n", + "])\n", + "\n", + "summary_prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a summarization expert.\"),\n", + " (\"user\", \"Summarize in one sentence: {text}\")\n", + "])\n", + "\n", + "# Use RunnableParallel to run both analyses simultaneously\n", + "analysis_chain = RunnableParallel(\n", + " {\n", + " \"sentiment\": sentiment_prompt | ChatOpenAI(temperature=0) | StrOutputParser(),\n", + " \"summary\": summary_prompt | ChatOpenAI(temperature=0) | StrOutputParser(),\n", + " \"original\": RunnablePassthrough() # Pass through the original input\n", + " }\n", + ")\n", + "\n", + "# Test it\n", + "sample_text = {\"text\": \"The product exceeded my expectations. Great quality!\"}\n", + "results = analysis_chain.invoke(sample_text)\n", + "\n", + "print(\"Sentiment:\", results[\"sentiment\"])\n", + "print(\"Summary:\", results[\"summary\"])\n", + "print(\"Original:\", results[\"original\"][\"text\"])" ] }, { - "cell_type": "code", - "execution_count": 54, - "id": "074f8806", - "metadata": { - "id": "074f8806" - }, - "outputs": [], + "cell_type": "markdown", + "id": "290aa2aa", + "metadata": {}, "source": [ - "llm_math_chain.verbose = False" + "### Batch Processing with LCEL\n", + "\n", + "LCEL chains support efficient batch processing using the `.batch()` method:" ] }, { "cell_type": "code", - "execution_count": 49, - "id": "465a6cbf", - "metadata": { - "id": "465a6cbf", - "outputId": "0207bf08-0db0-4d85-e3b9-ac7922f344c4" - }, + "execution_count": 14, + "id": "2b626aba", + "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "Q: What is the capital of France?\n", + "A: The capital of France is Paris.\n", + "\n", + "Q: Who wrote Romeo and Juliet?\n", + "A: William Shakespeare.\n", + "\n", + "Q: What is the speed of light?\n", + "A: The speed of light in a vacuum is approximately 299,792 kilometers per second (km/s).\n", + "\n" + ] } ], "source": [ - "llm_math_chain.verbose" + "# Create a simple question-answering chain\n", + "qa_prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful assistant. Answer concisely.\"),\n", + " (\"user\", \"{question}\")\n", + "])\n", + "\n", + "qa_chain = qa_prompt | ChatOpenAI(temperature=0) | StrOutputParser()\n", + "\n", + "# Batch of questions\n", + "questions = [\n", + " {\"question\": \"What is the capital of France?\"},\n", + " {\"question\": \"Who wrote Romeo and Juliet?\"},\n", + " {\"question\": \"What is the speed of light?\"}\n", + "]\n", + "\n", + "# Process all questions in batch\n", + "answers = qa_chain.batch(questions)\n", + "\n", + "# Display results\n", + "for q, a in zip(questions, answers):\n", + " print(f\"Q: {q['question']}\")\n", + " print(f\"A: {a}\\n\")" ] }, { @@ -906,7 +595,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "ml", + "display_name": "pinecone1", "language": "python", "name": "python3" }, @@ -920,12 +609,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" - }, - "vscode": { - "interpreter": { - "hash": "b8e7999f96e1b425e2d542f21b571f5a4be3e97158b0b46ea1b2500df63956ce" - } + "version": "3.11.4" } }, "nbformat": 4, diff --git a/learn/generation/langchain/handbook/03-langchain-conversational-memory.ipynb b/learn/generation/langchain/handbook/03-langchain-conversational-memory.ipynb index 402bdef9..0dfc6b31 100644 --- a/learn/generation/langchain/handbook/03-langchain-conversational-memory.ipynb +++ b/learn/generation/langchain/handbook/03-langchain-conversational-memory.ipynb @@ -37,16 +37,16 @@ "execution_count": 1, "id": "uZR3iGJJtdDE", "metadata": { - "id": "uZR3iGJJtdDE", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "uZR3iGJJtdDE", "outputId": "98873b1a-5688-4f64-c400-e17be707c56b" }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m344.0/344.0 KB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m70.1/70.1 KB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", @@ -246,8 +246,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", @@ -295,8 +295,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ " def _call(self, inputs: Dict[str, Any]) -> Dict[str, str]:\n", " known_values = self.prep_inputs(inputs.copy())\n", @@ -336,8 +336,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ " def _call(self, inputs: Dict[str, Any]) -> Dict[str, str]:\n", " known_values = self.prep_inputs(inputs.copy())\n", @@ -462,7 +462,6 @@ }, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "{'input': 'Good morning AI!',\n", @@ -470,8 +469,9 @@ " 'response': \" Good morning! It's a beautiful day today, isn't it? How can I help you?\"}" ] }, + "execution_count": 32, "metadata": {}, - "execution_count": 32 + "output_type": "execute_result" } ], "source": [ @@ -502,24 +502,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 179 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Is there anything else I can help you with?'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Is there anything else I can help you with?'" + ] }, + "execution_count": 33, "metadata": {}, - "execution_count": 33 + "output_type": "execute_result" } ], "source": [ @@ -543,24 +543,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 268 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Well, integrating Large Language Models with external knowledge can open up a lot of possibilities. For example, you could use them to generate more accurate and detailed summaries of text, or to answer questions about a given context more accurately. You could also use them to generate more accurate translations, or to generate more accurate predictions about future events.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Well, integrating Large Language Models with external knowledge can open up a lot of possibilities. For example, you could use them to generate more accurate and detailed summaries of text, or to answer questions about a given context more accurately. You could also use them to generate more accurate translations, or to generate more accurate predictions about future events.'" + ] }, + "execution_count": 34, "metadata": {}, - "execution_count": 34 + "output_type": "execute_result" } ], "source": [ @@ -584,24 +584,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 360 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' There are a variety of data sources that could be used to give context to a Large Language Model. These include structured data sources such as databases, unstructured data sources such as text documents, and even audio and video data sources. Additionally, you could use external knowledge sources such as Wikipedia or other online encyclopedias to provide additional context.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' There are a variety of data sources that could be used to give context to a Large Language Model. These include structured data sources such as databases, unstructured data sources such as text documents, and even audio and video data sources. Additionally, you could use external knowledge sources such as Wikipedia or other online encyclopedias to provide additional context.'" + ] }, + "execution_count": 35, "metadata": {}, - "execution_count": 35 + "output_type": "execute_result" } ], "source": [ @@ -625,24 +625,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 388 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'" + ] }, + "execution_count": 36, "metadata": {}, - "execution_count": 36 + "output_type": "execute_result" } ], "source": [ @@ -675,8 +675,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "\n", "Human: Good morning AI!\n", @@ -796,8 +796,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary.\n", "\n", @@ -851,24 +851,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 290 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "\" Good morning! It's a beautiful day today, isn't it? How can I help you?\"" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "\" Good morning! It's a beautiful day today, isn't it? How can I help you?\"" + ] }, + "execution_count": 40, "metadata": {}, - "execution_count": 40 + "output_type": "execute_result" } ], "source": [ @@ -894,24 +894,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 440 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "\" That sounds like an interesting project! I'm familiar with Large Language Models, but I'm not sure how they could be integrated with external knowledge. Could you tell me more about what you have in mind?\"" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "\" That sounds like an interesting project! I'm familiar with Large Language Models, but I'm not sure how they could be integrated with external knowledge. Could you tell me more about what you have in mind?\"" + ] }, + "execution_count": 41, "metadata": {}, - "execution_count": 41 + "output_type": "execute_result" } ], "source": [ @@ -935,24 +935,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 664 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' I can think of a few possibilities. One option is to use a large language model to generate a set of candidate answers to a given query, and then use external knowledge to filter out the most relevant answers. Another option is to use the large language model to generate a set of candidate answers, and then use external knowledge to score and rank the answers. Finally, you could use the large language model to generate a set of candidate answers, and then use external knowledge to refine the answers.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' I can think of a few possibilities. One option is to use a large language model to generate a set of candidate answers to a given query, and then use external knowledge to filter out the most relevant answers. Another option is to use the large language model to generate a set of candidate answers, and then use external knowledge to score and rank the answers. Finally, you could use the large language model to generate a set of candidate answers, and then use external knowledge to refine the answers.'" + ] }, + "execution_count": 42, "metadata": {}, - "execution_count": 42 + "output_type": "execute_result" } ], "source": [ @@ -976,24 +976,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 799 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' There are many different types of data sources that could be used to give context to the model. These could include structured data sources such as databases, unstructured data sources such as text documents, or even external APIs that provide access to external knowledge. Additionally, the model could be trained on a combination of these data sources to provide a more comprehensive understanding of the context.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' There are many different types of data sources that could be used to give context to the model. These could include structured data sources such as databases, unstructured data sources such as text documents, or even external APIs that provide access to external knowledge. Additionally, the model could be trained on a combination of these data sources to provide a more comprehensive understanding of the context.'" + ] }, + "execution_count": 43, "metadata": {}, - "execution_count": 43 + "output_type": "execute_result" } ], "source": [ @@ -1017,24 +1017,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 853 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Your aim is to explore the potential of integrating Large Language Models with external knowledge.'" + ] }, + "execution_count": 44, "metadata": {}, - "execution_count": 44 + "output_type": "execute_result" } ], "source": [ @@ -1057,8 +1057,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "\n", "The human greeted the AI with a good morning, to which the AI responded with a good morning and asked how it could help. The human expressed interest in exploring the potential of integrating Large Language Models with external knowledge, to which the AI responded positively and asked for more information. The human asked the AI to think of different possibilities, and the AI suggested three options: using the large language model to generate a set of candidate answers and then using external knowledge to filter out the most relevant answers, score and rank the answers, or refine the answers. The human then asked which data source types could be used to give context to the model, to which the AI responded that there are many different types of data sources that could be used, such as structured data sources, unstructured data sources, or external APIs. Additionally, the model could be trained on a combination of these data sources to provide a more comprehensive understanding of the context. The human then asked what their aim was again, to which the AI responded that their aim was to explore the potential of integrating Large Language Models with external knowledge.\n" @@ -1094,8 +1094,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Buffer memory conversation length: 334\n", "Summary memory conversation length: 219\n" @@ -1182,24 +1182,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 85 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "\" Good morning! It's a beautiful day today, isn't it? How can I help you?\"" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "\" Good morning! It's a beautiful day today, isn't it? How can I help you?\"" + ] }, + "execution_count": 61, "metadata": {}, - "execution_count": 61 + "output_type": "execute_result" } ], "source": [ @@ -1223,24 +1223,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 178 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Do you have any specific questions about this integration?'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Interesting! Large Language Models are a type of artificial intelligence that can process natural language and generate text. They can be used to generate text from a given context, or to answer questions about a given context. Integrating them with external knowledge can help them to better understand the context and generate more accurate results. Do you have any specific questions about this integration?'" + ] }, + "execution_count": 62, "metadata": {}, - "execution_count": 62 + "output_type": "execute_result" } ], "source": [ @@ -1264,24 +1264,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 233 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' There are many possibilities for integrating Large Language Models with external knowledge. For example, you could use external knowledge to provide additional context to the model, or to provide additional training data. You could also use external knowledge to help the model better understand the context of a given text, or to help it generate more accurate results.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' There are many possibilities for integrating Large Language Models with external knowledge. For example, you could use external knowledge to provide additional context to the model, or to provide additional training data. You could also use external knowledge to help the model better understand the context of a given text, or to help it generate more accurate results.'" + ] }, + "execution_count": 63, "metadata": {}, - "execution_count": 63 + "output_type": "execute_result" } ], "source": [ @@ -1305,24 +1305,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 245 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Data sources that could be used to give context to the model include text corpora, structured databases, and ontologies. Text corpora provide a large amount of text data that can be used to train the model and provide additional context. Structured databases provide structured data that can be used to provide additional context to the model. Ontologies provide a structured representation of knowledge that can be used to provide additional context to the model.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Data sources that could be used to give context to the model include text corpora, structured databases, and ontologies. Text corpora provide a large amount of text data that can be used to train the model and provide additional context. Structured databases provide structured data that can be used to provide additional context to the model. Ontologies provide a structured representation of knowledge that can be used to provide additional context to the model.'" + ] }, + "execution_count": 64, "metadata": {}, - "execution_count": 64 + "output_type": "execute_result" } ], "source": [ @@ -1346,24 +1346,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 186 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "' Your aim is to use data sources to give context to the model.'" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "' Your aim is to use data sources to give context to the model.'" + ] }, + "execution_count": 65, "metadata": {}, - "execution_count": 65 + "output_type": "execute_result" } ], "source": [ @@ -1420,8 +1420,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Human: What is my aim again?\n", "AI: Your aim is to use data sources to give context to the model.\n" @@ -1457,8 +1457,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Buffer memory conversation length: 334\n", "Summary memory conversation length: 219\n", @@ -1596,24 +1596,24 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Spent a total of 1565 tokens\n" ] }, { - "output_type": "execute_result", "data": { - "text/plain": [ - "\" Hi Human! My name is AI. It's nice to meet you. I like mangoes too! Did you know that mangoes are a great source of vitamins A and C?\"" - ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" - } + }, + "text/plain": [ + "\" Hi Human! My name is AI. It's nice to meet you. I like mangoes too! Did you know that mangoes are a great source of vitamins A and C?\"" + ] }, + "execution_count": 71, "metadata": {}, - "execution_count": 71 + "output_type": "execute_result" } ], "source": [ @@ -1646,14 +1646,14 @@ }, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "[('human', 'human', 'name'), ('human', 'mangoes', 'likes')]" ] }, + "execution_count": 72, "metadata": {}, - "execution_count": 72 + "output_type": "execute_result" } ], "source": [ @@ -1721,7 +1721,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "Python 3", + "display_name": "pinecone1", "language": "python", "name": "python3" }, @@ -1735,12 +1735,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.2" - }, - "vscode": { - "interpreter": { - "hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e" - } + "version": "3.11.4" } }, "nbformat": 4,