├── .gitignore ├── images ├── embeddings.png ├── stuffmethod.png ├── Router_Chain.png ├── SequentialChain.png ├── additionalmethods.png ├── vector_database_1.png ├── vector_database_2.png └── SimpleSequentialChain.png ├── Data.csv ├── README.md ├── L6-Agents.ipynb ├── L5-Evaluation.ipynb ├── L4-QnA.ipynb ├── L2-Memory.ipynb ├── L3-chains.ipynb └── L1-Model_prompt_parser.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | __pycache__ 3 | .env -------------------------------------------------------------------------------- /images/embeddings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/embeddings.png -------------------------------------------------------------------------------- /images/stuffmethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/stuffmethod.png -------------------------------------------------------------------------------- /images/Router_Chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/Router_Chain.png -------------------------------------------------------------------------------- /images/SequentialChain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/SequentialChain.png -------------------------------------------------------------------------------- /images/additionalmethods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/additionalmethods.png -------------------------------------------------------------------------------- /images/vector_database_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/vector_database_1.png -------------------------------------------------------------------------------- /images/vector_database_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/vector_database_2.png -------------------------------------------------------------------------------- /images/SimpleSequentialChain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksm26/LangChain-for-LLM-Application-Development/HEAD/images/SimpleSequentialChain.png -------------------------------------------------------------------------------- /Data.csv: -------------------------------------------------------------------------------- 1 | Product,Review 2 | Queen Size Sheet Set,"I ordered a king size set. My only criticism would be that I wish seller would offer the king size set with 4 pillowcases. I separately ordered a two pack of pillowcases so I could have a total of four. When I saw the two packages, it looked like the color did not exactly match. Customer service was excellent about sending me two more pillowcases so I would have four that matched. Excellent! For the cost of these sheets, I am satisfied with the characteristics and coolness of the sheets." 3 | Waterproof Phone Pouch,"I loved the waterproof sac, although the opening was made of a hard plastic. I don’t know if that would break easily. But I couldn’t turn my phone on, once it was in the pouch." 4 | Luxury Air Mattress,"This mattress had a small hole in the top of it (took forever to find where it was), and the patches that they provide did not work, maybe because it's the top of the mattress where it's kind of like fabric and a patch won't stick. Maybe I got unlucky with a defective mattress, but where's quality assurance for this company? That flat out should not happen. Emphasis on flat. Cause that's what the mattress was. Seriously horrible experience, ruined my friend's stay with me. Then they make you ship it back instead of just providing a refund, which is also super annoying to pack up an air mattress and take it to the UPS store. This company is the worst, and this mattress is the worst." 5 | Pillows Insert,"This is the best throw pillow fillers on Amazon. I’ve tried several others, and they’re all cheap and flat no matter how much fluffing you do. Once you toss these in the dryer after you remove them from the vacuum sealed shipping material, they fluff up great" 6 | "Milk Frother Handheld 7 | "," I loved this product. But they only seem to last a few months. The company was great replacing the first one (the frother falls out of the handle and can't be fixed). The after 4 months my second one did the same. I only use the frother for coffee once a day. It's not overuse or abuse. I'm very disappointed and will look for another. As I understand they will only replace once. Anyway, if you have one good luck." 8 | "L'Or Espresso Café  9 | ","Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur... 10 | Vieux lot ou contrefaçon !?" 11 | Hervidor de Agua Eléctrico,"Está lu bonita calienta muy rápido, es muy funcional, solo falta ver cuánto dura, solo llevo 3 días en funcionamiento." -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 [LangChain-for-LLM-Application-Development](https://www.deeplearning.ai/short-courses/langchain-for-llm-application-development/) 2 | 3 | 💻 Welcome to the "LangChain for LLM Application Development" course! This one-hour course, instructed by Harrison Chase, the creator of the LangChain framework, along with Andrew Ng, will equip you with essential skills to enhance the use cases and capabilities of language models in application development. 4 | 5 | **LangChain**: 🔗[GitHub](https://github.com/hwchase17/langchain), 📚[Documentation](https://python.langchain.com/docs/introduction/) 6 | 7 | ## Course Summary 8 | In this course, you will dive into various topics that will empower you to leverage the LangChain framework effectively. Here's what you can expect to learn and experience: 9 | 10 | 1. 📚 **Models, Prompts and Parsers**: Discover how to call Language Models (LLMs), provide prompts, and parse the responses. 11 | 2. 🧠 **Memories for LLMs**: Learn how to employ memories to store conversations and manage limited context space effectively. 12 | 3. ⛓️ **Chains**: Explore the creation of sequences of operations using LangChain. 13 | 14 |

15 | 16 | 17 | 18 |

19 | 20 | 4. 📄 **Question Answering over Documents**: Apply LLMs to your proprietary data and tailor them to meet specific use case requirements. 21 | 22 |

23 | 24 |

25 | 26 |

27 | 28 | 29 |

30 | 31 |

32 | 33 | 34 |

35 | 36 | 5. 👥 **Agents**: Gain insights into the emerging development of LLMs as reasoning agents. 37 | 38 | By the end of this course, you will have a solid foundation in using LangChain and will be equipped with a model that can serve as a starting point for developing your own applications using diffusion models. 39 | 40 | ## Key Points 41 | - 🔑 Learn LangChain directly from Harrison Chase, the creator of the framework. 42 | - 🤖 Apply LLMs to your proprietary data and develop personalized assistants and specialized chatbots. 43 | - 💡 Expand your utilization of LLMs through agents, chained calls, and memories. 44 | 45 | ## About the Instructors 46 | 🌟**Harrison Chase** is Co-Founder and CEO at LangChain. 47 | 48 | 🌟**Andrew Ng** is a renowned AI researcher, co-founder of Coursera, and the founder of DeepLearning.AI. With a wealth of knowledge and expertise in the field, Andrew has played a pivotal role in popularizing AI education. 49 | 50 | 🔗"LangChain for LLM Application Development" course. To enroll in the course or for further information, visit [deeplearning.ai](https://www.deeplearning.ai/). 51 | -------------------------------------------------------------------------------- /L6-Agents.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6f228e69", 6 | "metadata": {}, 7 | "source": [ 8 | "# LangChain: Agents\n", 9 | "## Outline:\n", 10 | "- Using built in LangChain tools: DuckDuckGo search and Wikipedia\n", 11 | "- Defining your own tools" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "id": "8e172f66", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "import os\n", 22 | "\n", 23 | "from dotenv import load_dotenv, find_dotenv\n", 24 | "_ = load_dotenv(find_dotenv()) # read local .env file\n", 25 | "\n", 26 | "import warnings\n", 27 | "warnings.filterwarnings(\"ignore\")" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "id": "4c03741b", 33 | "metadata": {}, 34 | "source": [ 35 | "## Built-in LangChain tools" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "id": "cb4512ba", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "#!pip install -U wikipedia" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 4, 51 | "id": "9caa5362", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "from langchain.agents.agent_toolkits import create_python_agent\n", 56 | "from langchain.agents import load_tools, initialize_agent\n", 57 | "from langchain.agents import AgentType\n", 58 | "from langchain.tools.python.tool import PythonREPLTool\n", 59 | "from langchain.python import PythonREPL\n", 60 | "from langchain.chat_models import ChatOpenAI" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 5, 66 | "id": "0e4da3cd", 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "llm = ChatOpenAI(temperature=0)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 6, 76 | "id": "01180aba", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "tools = load_tools([\"llm-math\",\"wikipedia\"], llm=llm)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 7, 86 | "id": "a81cc2f2", 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "agent= initialize_agent(\n", 91 | " tools, \n", 92 | " llm, \n", 93 | " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", 94 | " handle_parsing_errors=True,\n", 95 | " verbose = True)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "id": "57c2d2e3", 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "agent(\"What is the 25% of 300?\")" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "id": "ec75645c", 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "question = \"Tom M. Mitchell is an American computer scientist \\\n", 116 | "and the Founders University Professor at Carnegie Mellon University (CMU)\\\n", 117 | "what book did he write?\"\n", 118 | "result = agent(question) " 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "id": "f3cc6e01", 124 | "metadata": {}, 125 | "source": [ 126 | "## Python Agent" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 9, 132 | "id": "836e5414", 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "agent = create_python_agent(\n", 137 | " llm,\n", 138 | " tool=PythonREPLTool(),\n", 139 | " verbose=True\n", 140 | ")" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 10, 146 | "id": "1232cd0a", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "customer_list = [[\"Harrison\", \"Chase\"], \n", 151 | " [\"Lang\", \"Chain\"],\n", 152 | " [\"Dolly\", \"Too\"],\n", 153 | " [\"Elle\", \"Elem\"], \n", 154 | " [\"Geoff\",\"Fusion\"], \n", 155 | " [\"Trance\",\"Former\"],\n", 156 | " [\"Jen\",\"Ayai\"]\n", 157 | " ]" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "id": "fb589b8a", 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "agent.run(f\"\"\"Sort these customers by \\\n", 168 | "last name and then first name \\\n", 169 | "and print the output: {customer_list}\"\"\") " 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "id": "c576e9a3", 175 | "metadata": {}, 176 | "source": [ 177 | "### View detailed outputs of the chains" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "id": "56d4d84b", 184 | "metadata": {}, 185 | "outputs": [], 186 | "source": [ 187 | "import langchain\n", 188 | "langchain.debug=True\n", 189 | "agent.run(f\"\"\"Sort these customers by \\\n", 190 | "last name and then first name \\\n", 191 | "and print the output: {customer_list}\"\"\") \n", 192 | "langchain.debug=False" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "id": "50a2fbaa", 198 | "metadata": {}, 199 | "source": [ 200 | "## Define your own tool" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 14, 206 | "id": "c178747f", 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [ 210 | "#!pip install DateTime" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 15, 216 | "id": "a5a7987d", 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "from langchain.agents import tool\n", 221 | "from datetime import date" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 16, 227 | "id": "866abd50", 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "@tool\n", 232 | "def time(text: str) -> str:\n", 233 | " \"\"\"Returns todays date, use this for any \\\n", 234 | " questions related to knowing todays date. \\\n", 235 | " The input should always be an empty string, \\\n", 236 | " and this function will always return todays \\\n", 237 | " date - any date mathmatics should occur \\\n", 238 | " outside this function.\"\"\"\n", 239 | " return str(date.today())" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 17, 245 | "id": "874d4ad3", 246 | "metadata": {}, 247 | "outputs": [], 248 | "source": [ 249 | "agent= initialize_agent(\n", 250 | " tools + [time], \n", 251 | " llm, \n", 252 | " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", 253 | " handle_parsing_errors=True,\n", 254 | " verbose = True)" 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "id": "f15a6453", 260 | "metadata": {}, 261 | "source": [ 262 | "**Note**:\n", 263 | "\n", 264 | "The agent will sometimes come to the wrong conclusion (agents are a work in progress!).\n", 265 | "\n", 266 | "If it does, please try running it again." 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "id": "730edea9", 273 | "metadata": {}, 274 | "outputs": [], 275 | "source": [ 276 | "try:\n", 277 | " result = agent(\"whats the date today?\") \n", 278 | "except: \n", 279 | " print(\"exception on external access\")" 280 | ] 281 | } 282 | ], 283 | "metadata": { 284 | "kernelspec": { 285 | "display_name": "Python 3 (ipykernel)", 286 | "language": "python", 287 | "name": "python3" 288 | }, 289 | "language_info": { 290 | "codemirror_mode": { 291 | "name": "ipython", 292 | "version": 3 293 | }, 294 | "file_extension": ".py", 295 | "mimetype": "text/x-python", 296 | "name": "python", 297 | "nbconvert_exporter": "python", 298 | "pygments_lexer": "ipython3", 299 | "version": "3.10.9" 300 | } 301 | }, 302 | "nbformat": 4, 303 | "nbformat_minor": 5 304 | } 305 | -------------------------------------------------------------------------------- /L5-Evaluation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ec122939", 6 | "metadata": {}, 7 | "source": [ 8 | "# LangChain: Evaluation\n", 9 | "## Outline:\n", 10 | "- Example generation\n", 11 | "- Manual evaluation (and debuging)\n", 12 | "- LLM-assisted evaluation" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "fe2399fd", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "import os\n", 23 | "\n", 24 | "from dotenv import load_dotenv, find_dotenv\n", 25 | "_ = load_dotenv(find_dotenv()) # read local .env file" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "id": "977b1b58", 31 | "metadata": {}, 32 | "source": [ 33 | "## Create our QandA application" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "id": "09965ca0", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "from langchain.chains import RetrievalQA\n", 44 | "from langchain.chat_models import ChatOpenAI\n", 45 | "from langchain.document_loaders import CSVLoader\n", 46 | "from langchain.indexes import VectorstoreIndexCreator\n", 47 | "from langchain.vectorstores import DocArrayInMemorySearch" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "id": "54233d48", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "file = 'OutdoorClothingCatalog_1000.csv'\n", 58 | "loader = CSVLoader(file_path=file)\n", 59 | "data = loader.load()" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "id": "874d8824", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "index = VectorstoreIndexCreator(\n", 70 | " vectorstore_cls=DocArrayInMemorySearch\n", 71 | ").from_loaders([loader])" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "id": "6b5d5a0e", 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "llm = ChatOpenAI(temperature = 0.0)\n", 82 | "qa = RetrievalQA.from_chain_type(\n", 83 | " llm=llm, \n", 84 | " chain_type=\"stuff\", \n", 85 | " retriever=index.vectorstore.as_retriever(), \n", 86 | " verbose=True,\n", 87 | " chain_type_kwargs = {\n", 88 | " \"document_separator\": \"<<<<>>>>>\"\n", 89 | " }\n", 90 | ")" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "id": "8117176a", 96 | "metadata": {}, 97 | "source": [ 98 | "## Coming up with test datapoints" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "id": "85a10b31", 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "data[10]" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "id": "5422419e", 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "data[11]" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "id": "f3aeb7bf", 124 | "metadata": {}, 125 | "source": [ 126 | "### Hard-coded examples" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 6, 132 | "id": "4b893c9c", 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "examples = [\n", 137 | " {\n", 138 | " \"query\": \"Do the Cozy Comfort Pullover Set\\\n", 139 | " have side pockets?\",\n", 140 | " \"answer\": \"Yes\"\n", 141 | " },\n", 142 | " {\n", 143 | " \"query\": \"What collection is the Ultra-Lofty \\\n", 144 | " 850 Stretch Down Hooded Jacket from?\",\n", 145 | " \"answer\": \"The DownTek collection\"\n", 146 | " }\n", 147 | "]" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "id": "4ae2343e", 153 | "metadata": {}, 154 | "source": [ 155 | "## LLM-Generated examples" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 7, 161 | "id": "a0619d58", 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "from langchain.evaluation.qa import QAGenerateChain" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 8, 171 | "id": "7b1dd201", 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "example_gen_chain = QAGenerateChain.from_llm(ChatOpenAI())" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "id": "8416e525", 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "new_examples = example_gen_chain.apply_and_parse(\n", 186 | " [{\"doc\": t} for t in data[:5]]\n", 187 | ")" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": null, 193 | "id": "778d7877", 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "new_examples[0]" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "id": "ab295d1c", 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "data[0]" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "id": "f9686dce", 213 | "metadata": {}, 214 | "source": [ 215 | "### Combine examples" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "id": "49bb016b", 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "examples += new_examples" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "id": "d0df1d6c", 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "qa.run(examples[0][\"query\"])" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "id": "21246340", 241 | "metadata": {}, 242 | "source": [ 243 | "## Manual Evaluation" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 10, 249 | "id": "e396a348", 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "import langchain\n", 254 | "langchain.debug = True" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "id": "9b7197e5", 261 | "metadata": {}, 262 | "outputs": [], 263 | "source": [ 264 | "qa.run(examples[0][\"query\"])" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "id": "36969f31", 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "# Turn off the debug mode\n", 275 | "langchain.debug = False" 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "id": "c2f7908f", 281 | "metadata": {}, 282 | "source": [ 283 | "### LLM assisted evaluation" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "id": "60e87947", 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "predictions = qa.apply(examples)" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": 11, 299 | "id": "d76db060", 300 | "metadata": {}, 301 | "outputs": [], 302 | "source": [ 303 | "from langchain.evaluation.qa import QAEvalChain" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 12, 309 | "id": "6b4bf73b", 310 | "metadata": {}, 311 | "outputs": [], 312 | "source": [ 313 | "llm = ChatOpenAI(temperature=0)\n", 314 | "eval_chain = QAEvalChain.from_llm(llm)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": null, 320 | "id": "f62c5ed2", 321 | "metadata": {}, 322 | "outputs": [], 323 | "source": [ 324 | "for i, eg in enumerate(examples):\n", 325 | " print(f\"Example {i}:\")\n", 326 | " print(\"Question: \" + predictions[i]['query'])\n", 327 | " print(\"Real Answer: \" + predictions[i]['answer'])\n", 328 | " print(\"Predicted Answer: \" + predictions[i]['result'])\n", 329 | " print(\"Predicted Grade: \" + graded_outputs[i]['text'])\n", 330 | " print()" 331 | ] 332 | } 333 | ], 334 | "metadata": { 335 | "kernelspec": { 336 | "display_name": "Python 3 (ipykernel)", 337 | "language": "python", 338 | "name": "python3" 339 | }, 340 | "language_info": { 341 | "codemirror_mode": { 342 | "name": "ipython", 343 | "version": 3 344 | }, 345 | "file_extension": ".py", 346 | "mimetype": "text/x-python", 347 | "name": "python", 348 | "nbconvert_exporter": "python", 349 | "pygments_lexer": "ipython3", 350 | "version": "3.10.9" 351 | } 352 | }, 353 | "nbformat": 4, 354 | "nbformat_minor": 5 355 | } 356 | -------------------------------------------------------------------------------- /L4-QnA.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "cb3c3632", 6 | "metadata": {}, 7 | "source": [ 8 | "# LangChain: Q&A over Documents\n", 9 | "An example might be a tool that would allow you to query a product catalog for items of interest." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "id": "add77317", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "#pip install --upgrade langchain" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "id": "d142da8a", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "import os\n", 30 | "\n", 31 | "from dotenv import load_dotenv, find_dotenv\n", 32 | "_ = load_dotenv(find_dotenv()) # read local .env file" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "id": "c0df98d3", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "from langchain.chains import RetrievalQA\n", 43 | "from langchain.chat_models import ChatOpenAI\n", 44 | "from langchain.document_loaders import CSVLoader\n", 45 | "from langchain.vectorstores import DocArrayInMemorySearch\n", 46 | "from IPython.display import display, Markdown" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 4, 52 | "id": "9a97b260", 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "file = 'OutdoorClothingCatalog_1000.csv'\n", 57 | "loader = CSVLoader(file_path=file)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 5, 63 | "id": "ae221086", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "from langchain.indexes import VectorstoreIndexCreator" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 7, 73 | "id": "37947eea", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "#pip install docarray" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "id": "07362cb9", 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "index = VectorstoreIndexCreator(\n", 88 | " vectorstore_cls=DocArrayInMemorySearch\n", 89 | ").from_loaders([loader])" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 9, 95 | "id": "5cd740a6", 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "query =\"Please list all your shirts with sun protection \\\n", 100 | "in a table in markdown and summarize each one.\"" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "id": "e237aa1a", 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "response = index.query(query)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "id": "1920e381", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "display(Markdown(response))" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "id": "29646b6b", 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "loader = CSVLoader(file_path=file)" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "6b952a9e", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "docs = loader.load()" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "id": "1d09a29e", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "docs[0]" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "52f4824b", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "from langchain.embeddings import OpenAIEmbeddings\n", 161 | "embeddings = OpenAIEmbeddings()" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "ff61ce20", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [ 171 | "embed = embeddings.embed_query(\"Hi my name is Harrison\")" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "id": "43ff167c", 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "print(len(embed))" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": null, 187 | "id": "60b58eeb", 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "print(embed[:5])" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": null, 197 | "id": "cfe6aad2", 198 | "metadata": {}, 199 | "outputs": [], 200 | "source": [ 201 | "db = DocArrayInMemorySearch.from_documents(\n", 202 | " docs, \n", 203 | " embeddings\n", 204 | ")" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "id": "4b625f97", 211 | "metadata": {}, 212 | "outputs": [], 213 | "source": [ 214 | "query = \"Please suggest a shirt with sunblocking\"" 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": null, 220 | "id": "16ce5392", 221 | "metadata": {}, 222 | "outputs": [], 223 | "source": [ 224 | "docs = db.similarity_search(query)" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "id": "fd97048d", 231 | "metadata": {}, 232 | "outputs": [], 233 | "source": [ 234 | "len(docs)" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "id": "1a2c05aa", 241 | "metadata": {}, 242 | "outputs": [], 243 | "source": [ 244 | "docs[0]" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "id": "1a9d02d3", 251 | "metadata": {}, 252 | "outputs": [], 253 | "source": [ 254 | "retriever = db.as_retriever()" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "id": "de623646", 261 | "metadata": {}, 262 | "outputs": [], 263 | "source": [ 264 | "llm = ChatOpenAI(temperature = 0.0)" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "id": "a7241259", 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "qdocs = \"\".join([docs[i].page_content for i in range(len(docs))])" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "id": "0930226f", 281 | "metadata": {}, 282 | "outputs": [], 283 | "source": [ 284 | "response = llm.call_as_llm(f\"{qdocs} Question: Please list all your \\\n", 285 | "shirts with sun protection in a table in markdown and summarize each one.\") " 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": null, 291 | "id": "593aedfc", 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "display(Markdown(response))" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": null, 301 | "id": "b65ad35a", 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [ 305 | "qa_stuff = RetrievalQA.from_chain_type(\n", 306 | " llm=llm, \n", 307 | " chain_type=\"stuff\", \n", 308 | " retriever=retriever, \n", 309 | " verbose=True\n", 310 | ")" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": null, 316 | "id": "c2919c2e", 317 | "metadata": {}, 318 | "outputs": [], 319 | "source": [ 320 | "query = \"Please list all your shirts with sun protection in a table \\\n", 321 | "in markdown and summarize each one.\"" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "id": "430f90b7", 328 | "metadata": {}, 329 | "outputs": [], 330 | "source": [ 331 | "response = qa_stuff.run(query)" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": null, 337 | "id": "c5cfcceb", 338 | "metadata": {}, 339 | "outputs": [], 340 | "source": [ 341 | "display(Markdown(response))" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": null, 347 | "id": "779d94c3", 348 | "metadata": {}, 349 | "outputs": [], 350 | "source": [ 351 | "response = index.query(query, llm=llm)" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "id": "70636236", 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [ 361 | "index = VectorstoreIndexCreator(\n", 362 | " vectorstore_cls=DocArrayInMemorySearch,\n", 363 | " embedding=embeddings,\n", 364 | ").from_loaders([loader])" 365 | ] 366 | } 367 | ], 368 | "metadata": { 369 | "kernelspec": { 370 | "display_name": "Python 3 (ipykernel)", 371 | "language": "python", 372 | "name": "python3" 373 | }, 374 | "language_info": { 375 | "codemirror_mode": { 376 | "name": "ipython", 377 | "version": 3 378 | }, 379 | "file_extension": ".py", 380 | "mimetype": "text/x-python", 381 | "name": "python", 382 | "nbconvert_exporter": "python", 383 | "pygments_lexer": "ipython3", 384 | "version": "3.10.9" 385 | } 386 | }, 387 | "nbformat": 4, 388 | "nbformat_minor": 5 389 | } 390 | -------------------------------------------------------------------------------- /L2-Memory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "22643b33", 6 | "metadata": {}, 7 | "source": [ 8 | "# LangChain: Memory\n", 9 | "\n", 10 | "## Outline\n", 11 | "- ConversationBufferMemory\n", 12 | "- ConversationBufferWindowMemory\n", 13 | "- ConversationTokenBufferMemory\n", 14 | "- ConversationSummaryMemory" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "id": "27d8948c", 20 | "metadata": {}, 21 | "source": [ 22 | "## ConversationBufferMemory" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 19, 28 | "id": "64224484", 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import os\n", 33 | "\n", 34 | "from dotenv import load_dotenv, find_dotenv\n", 35 | "_ = load_dotenv(find_dotenv()) # read local .env file\n", 36 | "\n", 37 | "# import warnings\n", 38 | "# warnings.filterwarnings('ignore')" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 20, 44 | "id": "0be64d03", 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "from langchain.chat_models import ChatOpenAI\n", 49 | "from langchain.chains import ConversationChain\n", 50 | "from langchain.memory import ConversationBufferMemory\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 21, 56 | "id": "bcf8cdb0", 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "llm = ChatOpenAI(temperature=0.0)\n", 61 | "memory = ConversationBufferMemory()\n", 62 | "conversation = ConversationChain(\n", 63 | " llm=llm, \n", 64 | " verbose=True,\n", 65 | " memory = memory\n", 66 | ")" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "91b903be", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "conversation.predict(input=\"Hi, my name is Andrew\")" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "id": "9963721e", 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "conversation.predict(input=\"What is 1+1?\")" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "id": "e77d0adb", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "conversation.predict(input=\"What is my name?\")" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "id": "1c2bf9f0", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "memory.load_memory_variables({})" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "id": "b19fb0e4", 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [ 116 | "memory = ConversationBufferMemory()" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "id": "4c6056fe", 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "memory.save_context({\"input\": \"Hi\"}, \n", 127 | " {\"output\": \"What's up\"})" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "id": "513e13a9", 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "print(memory.buffer)" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "id": "e97fab09", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "memory.load_memory_variables({})" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "id": "9d4b10ab", 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "memory.save_context({\"input\": \"Not much, just hanging\"}, \n", 158 | " {\"output\": \"Cool\"})" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "id": "a539e0cc", 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [ 168 | "memory.load_memory_variables({})" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "id": "638c5862", 174 | "metadata": {}, 175 | "source": [ 176 | "## Memory\n", 177 | "Large Language Models are 'stateless'\n", 178 | "- Each transaction is independent \n", 179 | "\n", 180 | "Chatbots appear to have memory ny providing the full conversation as 'context'\n", 181 | "\n", 182 | "LangChain provides several kinds of 'memory' to store and accumulate the conversation" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "id": "08d366cf", 188 | "metadata": {}, 189 | "source": [ 190 | "## ConversationBufferWindowMemory" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 23, 196 | "id": "7f210ffa", 197 | "metadata": {}, 198 | "outputs": [], 199 | "source": [ 200 | "from langchain.memory import ConversationBufferWindowMemory" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 24, 206 | "id": "acc95800", 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [ 210 | "memory = ConversationBufferWindowMemory(k=1) " 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 25, 216 | "id": "53f867a9", 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "memory.save_context({\"input\": \"Hi\"},\n", 221 | " {\"output\": \"What's up\"})\n", 222 | "memory.save_context({\"input\": \"Not much, just hanging\"},\n", 223 | " {\"output\": \"Cool\"})" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 26, 229 | "id": "a9605b29", 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "data": { 234 | "text/plain": [ 235 | "{'history': 'Human: Not much, just hanging\\nAI: Cool'}" 236 | ] 237 | }, 238 | "execution_count": 26, 239 | "metadata": {}, 240 | "output_type": "execute_result" 241 | } 242 | ], 243 | "source": [ 244 | "memory.load_memory_variables({})" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 27, 250 | "id": "4b3130e3", 251 | "metadata": {}, 252 | "outputs": [], 253 | "source": [ 254 | "llm = ChatOpenAI(temperature=0.0)\n", 255 | "memory = ConversationBufferWindowMemory(k=1) # just remember 1 conversational exchange\n", 256 | "conversation = ConversationChain(\n", 257 | " llm=llm, \n", 258 | " memory = memory,\n", 259 | " verbose=False\n", 260 | ")" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "id": "9756e140", 267 | "metadata": {}, 268 | "outputs": [], 269 | "source": [ 270 | "conversation.predict(input=\"Hi, my name is Andrew\")" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "id": "6110490d", 277 | "metadata": {}, 278 | "outputs": [], 279 | "source": [ 280 | "conversation.predict(input=\"What is 1+1?\")" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": null, 286 | "id": "53292aa0", 287 | "metadata": {}, 288 | "outputs": [], 289 | "source": [ 290 | "conversation.predict(input=\"What is my name?\")" 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "id": "3f7acfed", 296 | "metadata": {}, 297 | "source": [ 298 | "## ConversationTokenBufferMemory" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 30, 304 | "id": "d365a523", 305 | "metadata": {}, 306 | "outputs": [], 307 | "source": [ 308 | "#!pip install tiktoken" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 31, 314 | "id": "4dad29d2", 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "from langchain.memory import ConversationTokenBufferMemory\n", 319 | "from langchain.llms import OpenAI\n", 320 | "llm = ChatOpenAI(temperature=0.0)" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 32, 326 | "id": "65ad1561", 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", 331 | "memory.save_context({\"input\": \"AI is what?!\"},\n", 332 | " {\"output\": \"Amazing!\"})\n", 333 | "memory.save_context({\"input\": \"Backpropagation is what?\"},\n", 334 | " {\"output\": \"Beautiful!\"})\n", 335 | "memory.save_context({\"input\": \"Chatbots are what?\"}, \n", 336 | " {\"output\": \"Charming!\"})" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 33, 342 | "id": "6a4ef354", 343 | "metadata": {}, 344 | "outputs": [ 345 | { 346 | "data": { 347 | "text/plain": [ 348 | "{'history': 'AI: Beautiful!\\nHuman: Chatbots are what?\\nAI: Charming!'}" 349 | ] 350 | }, 351 | "execution_count": 33, 352 | "metadata": {}, 353 | "output_type": "execute_result" 354 | } 355 | ], 356 | "source": [ 357 | "memory.load_memory_variables({})" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "id": "63f7c539", 363 | "metadata": {}, 364 | "source": [ 365 | "## ConversationSummaryMemory" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 34, 371 | "id": "8faf8b89", 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [ 375 | "from langchain.memory import ConversationSummaryBufferMemory\n" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": null, 381 | "id": "86f7ff84", 382 | "metadata": {}, 383 | "outputs": [], 384 | "source": [ 385 | "# create a long string\n", 386 | "schedule = \"There is a meeting at 8am with your product team. \\\n", 387 | "You will need your powerpoint presentation prepared. \\\n", 388 | "9am-12pm have time to work on your LangChain \\\n", 389 | "project which will go quickly because Langchain is such a powerful tool. \\\n", 390 | "At Noon, lunch at the italian resturant with a customer who is driving \\\n", 391 | "from over an hour away to meet you to understand the latest in AI. \\\n", 392 | "Be sure to bring your laptop to show the latest LLM demo.\"\n", 393 | "\n", 394 | "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)\n", 395 | "memory.save_context({\"input\": \"Hello\"}, {\"output\": \"What's up\"})\n", 396 | "memory.save_context({\"input\": \"Not much, just hanging\"},\n", 397 | " {\"output\": \"Cool\"})\n", 398 | "memory.save_context({\"input\": \"What is on the schedule today?\"}, \n", 399 | " {\"output\": f\"{schedule}\"})" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": null, 405 | "id": "68a6bf1a", 406 | "metadata": {}, 407 | "outputs": [], 408 | "source": [ 409 | "memory.load_memory_variables({})" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "id": "d085b3a1", 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [ 419 | "conversation = ConversationChain(\n", 420 | " llm=llm, \n", 421 | " memory = memory,\n", 422 | " verbose=True\n", 423 | ")" 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "execution_count": null, 429 | "id": "17384ba8", 430 | "metadata": {}, 431 | "outputs": [], 432 | "source": [ 433 | "conversation.predict(input=\"What would be a good demo to show?\")" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": null, 439 | "id": "4eabfb36", 440 | "metadata": {}, 441 | "outputs": [], 442 | "source": [ 443 | "memory.load_memory_variables({})" 444 | ] 445 | } 446 | ], 447 | "metadata": { 448 | "kernelspec": { 449 | "display_name": "Python 3 (ipykernel)", 450 | "language": "python", 451 | "name": "python3" 452 | }, 453 | "language_info": { 454 | "codemirror_mode": { 455 | "name": "ipython", 456 | "version": 3 457 | }, 458 | "file_extension": ".py", 459 | "mimetype": "text/x-python", 460 | "name": "python", 461 | "nbconvert_exporter": "python", 462 | "pygments_lexer": "ipython3", 463 | "version": "3.10.9" 464 | } 465 | }, 466 | "nbformat": 4, 467 | "nbformat_minor": 5 468 | } 469 | -------------------------------------------------------------------------------- /L3-chains.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "34767ee0", 6 | "metadata": {}, 7 | "source": [ 8 | "# Chains in LangChain\n", 9 | "\n", 10 | "## Outline\n", 11 | "- LLMChain\n", 12 | "- Sequential Chains\n", 13 | " - SimpleSequentialChain\n", 14 | " - SequentialChain\n", 15 | "- Router Chain" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 8, 21 | "id": "4638c236", 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "import warnings\n", 26 | "warnings.filterwarnings('ignore')" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 9, 32 | "id": "8a475133", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import os\n", 37 | "\n", 38 | "from dotenv import load_dotenv, find_dotenv\n", 39 | "_ = load_dotenv(find_dotenv()) # read local .env file" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 10, 45 | "id": "3303e86e", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "#!pip install pandas" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 11, 55 | "id": "ad389ea1", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "import pandas as pd\n", 60 | "df = pd.read_csv('Data.csv')" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 12, 66 | "id": "c23fd437", 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "data": { 71 | "text/html": [ 72 | "
\n", 73 | "\n", 86 | "\n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | "
ProductReview
0Queen Size Sheet SetI ordered a king size set. My only criticism w...
1Waterproof Phone PouchI loved the waterproof sac, although the openi...
2Luxury Air MattressThis mattress had a small hole in the top of i...
3Pillows InsertThis is the best throw pillow fillers on Amazo...
4Milk Frother Handheld\\nI loved this product. But they only seem to l...
\n", 122 | "
" 123 | ], 124 | "text/plain": [ 125 | " Product Review\n", 126 | "0 Queen Size Sheet Set I ordered a king size set. My only criticism w...\n", 127 | "1 Waterproof Phone Pouch I loved the waterproof sac, although the openi...\n", 128 | "2 Luxury Air Mattress This mattress had a small hole in the top of i...\n", 129 | "3 Pillows Insert This is the best throw pillow fillers on Amazo...\n", 130 | "4 Milk Frother Handheld\\n  I loved this product. But they only seem to l..." 131 | ] 132 | }, 133 | "execution_count": 12, 134 | "metadata": {}, 135 | "output_type": "execute_result" 136 | } 137 | ], 138 | "source": [ 139 | "df.head()" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "id": "b7919165", 145 | "metadata": {}, 146 | "source": [ 147 | "## LLMChain" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 13, 153 | "id": "8286d847", 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "from langchain.chat_models import ChatOpenAI # model\n", 158 | "from langchain.prompts import ChatPromptTemplate # prompt\n", 159 | "from langchain.chains import LLMChain # chain" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 14, 165 | "id": "29e738a4", 166 | "metadata": {}, 167 | "outputs": [], 168 | "source": [ 169 | "llm = ChatOpenAI(temperature=0.9)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 15, 175 | "id": "a032aa20", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "prompt = ChatPromptTemplate.from_template(\n", 180 | " \"What is the best name to describe \\\n", 181 | " a company that makes {product}?\"\n", 182 | ")" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 16, 188 | "id": "cdc0db5f", 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [ 192 | "chain = LLMChain(llm=llm, prompt=prompt)" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": null, 198 | "id": "ce47e3e6", 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "product = \"Queen Size Sheet Set\"\n", 203 | "chain.run(product)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "id": "b49a5cf8", 209 | "metadata": {}, 210 | "source": [ 211 | "## SimpleSequentialChain\n", 212 | "Single Input Single Output" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 14, 218 | "id": "0f7b1501", 219 | "metadata": {}, 220 | "outputs": [], 221 | "source": [ 222 | "from langchain.chains import SimpleSequentialChain" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 15, 228 | "id": "4a9070e3", 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "llm = ChatOpenAI(temperature=0.9)\n", 233 | "\n", 234 | "# prompt template 1\n", 235 | "first_prompt = ChatPromptTemplate.from_template(\n", 236 | " \"What is the best name to describe \\\n", 237 | " a company that makes {product}?\"\n", 238 | ")\n", 239 | "\n", 240 | "# Chain 1\n", 241 | "chain_one = LLMChain(llm=llm, prompt=first_prompt)" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 16, 247 | "id": "1842b484", 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [ 251 | "\n", 252 | "# prompt template 2\n", 253 | "second_prompt = ChatPromptTemplate.from_template(\n", 254 | " \"Write a 20 words description for the following \\\n", 255 | " company:{company_name}\"\n", 256 | ")\n", 257 | "# chain 2\n", 258 | "chain_two = LLMChain(llm=llm, prompt=second_prompt)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": 17, 264 | "id": "ac65946f", 265 | "metadata": {}, 266 | "outputs": [], 267 | "source": [ 268 | "overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],\n", 269 | " verbose=True\n", 270 | " )" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "id": "0704a86a", 277 | "metadata": {}, 278 | "outputs": [], 279 | "source": [ 280 | "overall_simple_chain.run(product)" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "id": "d453316e", 286 | "metadata": {}, 287 | "source": [ 288 | "## SequentialChain\n", 289 | "Multiple Input Multiple Output" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 18, 295 | "id": "077b357d", 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "from langchain.chains import SequentialChain" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 19, 305 | "id": "74cb911d", 306 | "metadata": {}, 307 | "outputs": [], 308 | "source": [ 309 | "llm = ChatOpenAI(temperature=0.9)\n", 310 | "\n", 311 | "# prompt template 1: translate to english\n", 312 | "first_prompt = ChatPromptTemplate.from_template(\n", 313 | " \"Translate the following review to english:\"\n", 314 | " \"\\n\\n{Review}\"\n", 315 | ")\n", 316 | "# chain 1: input= Review and output= English_Review\n", 317 | "chain_one = LLMChain(llm=llm, prompt=first_prompt, \n", 318 | " output_key=\"English_Review\"\n", 319 | " )" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 20, 325 | "id": "c658e0f1", 326 | "metadata": {}, 327 | "outputs": [], 328 | "source": [ 329 | "second_prompt = ChatPromptTemplate.from_template(\n", 330 | " \"Can you summarize the following review in 1 sentence:\"\n", 331 | " \"\\n\\n{English_Review}\"\n", 332 | ")\n", 333 | "# chain 2: input= English_Review and output= summary\n", 334 | "chain_two = LLMChain(llm=llm, prompt=second_prompt, \n", 335 | " output_key=\"summary\"\n", 336 | " )" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 21, 342 | "id": "411ed743", 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "# prompt template 3: translate to english\n", 347 | "third_prompt = ChatPromptTemplate.from_template(\n", 348 | " \"What language is the following review:\\n\\n{Review}\"\n", 349 | ")\n", 350 | "# chain 3: input= Review and output= language\n", 351 | "chain_three = LLMChain(llm=llm, prompt=third_prompt,\n", 352 | " output_key=\"language\"\n", 353 | " )" 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 22, 359 | "id": "5b678786", 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "\n", 364 | "# prompt template 4: follow up message\n", 365 | "fourth_prompt = ChatPromptTemplate.from_template(\n", 366 | " \"Write a follow up response to the following \"\n", 367 | " \"summary in the specified language:\"\n", 368 | " \"\\n\\nSummary: {summary}\\n\\nLanguage: {language}\"\n", 369 | ")\n", 370 | "# chain 4: input= summary, language and output= followup_message\n", 371 | "chain_four = LLMChain(llm=llm, prompt=fourth_prompt,\n", 372 | " output_key=\"followup_message\"\n", 373 | " )" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 23, 379 | "id": "4e65cd39", 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [ 383 | "# overall_chain: input= Review \n", 384 | "# and output= English_Review,summary, followup_message\n", 385 | "overall_chain = SequentialChain(\n", 386 | " chains=[chain_one, chain_two, chain_three, chain_four],\n", 387 | " input_variables=[\"Review\"],\n", 388 | " output_variables=[\"English_Review\", \"summary\",\"followup_message\"],\n", 389 | " verbose=True\n", 390 | ")" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 24, 396 | "id": "4fc6b6a8", 397 | "metadata": {}, 398 | "outputs": [ 399 | { 400 | "data": { 401 | "text/plain": [ 402 | "\"Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur...\\nVieux lot ou contrefaçon !?\"" 403 | ] 404 | }, 405 | "execution_count": 24, 406 | "metadata": {}, 407 | "output_type": "execute_result" 408 | } 409 | ], 410 | "source": [ 411 | "df.Review[5]" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "id": "c3edc1e6", 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "review = df.Review[5]\n", 422 | "overall_chain(review)" 423 | ] 424 | }, 425 | { 426 | "cell_type": "markdown", 427 | "id": "3175a5f6", 428 | "metadata": {}, 429 | "source": [ 430 | "## Router Chain" 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": 25, 436 | "id": "6dfe6cf4", 437 | "metadata": {}, 438 | "outputs": [], 439 | "source": [ 440 | "physics_template = \"\"\"You are a very smart physics professor. \\\n", 441 | "You are great at answering questions about physics in a concise\\\n", 442 | "and easy to understand manner. \\\n", 443 | "When you don't know the answer to a question you admit\\\n", 444 | "that you don't know.\n", 445 | "\n", 446 | "Here is a question:\n", 447 | "{input}\"\"\"\n", 448 | "\n", 449 | "\n", 450 | "math_template = \"\"\"You are a very good mathematician. \\\n", 451 | "You are great at answering math questions. \\\n", 452 | "You are so good because you are able to break down \\\n", 453 | "hard problems into their component parts, \n", 454 | "answer the component parts, and then put them together\\\n", 455 | "to answer the broader question.\n", 456 | "\n", 457 | "Here is a question:\n", 458 | "{input}\"\"\"\n", 459 | "\n", 460 | "history_template = \"\"\"You are a very good historian. \\\n", 461 | "You have an excellent knowledge of and understanding of people,\\\n", 462 | "events and contexts from a range of historical periods. \\\n", 463 | "You have the ability to think, reflect, debate, discuss and \\\n", 464 | "evaluate the past. You have a respect for historical evidence\\\n", 465 | "and the ability to make use of it to support your explanations \\\n", 466 | "and judgements.\n", 467 | "\n", 468 | "Here is a question:\n", 469 | "{input}\"\"\"\n", 470 | "\n", 471 | "\n", 472 | "computerscience_template = \"\"\" You are a successful computer scientist.\\\n", 473 | "You have a passion for creativity, collaboration,\\\n", 474 | "forward-thinking, confidence, strong problem-solving capabilities,\\\n", 475 | "understanding of theories and algorithms, and excellent communication \\\n", 476 | "skills. You are great at answering coding questions. \\\n", 477 | "You are so good because you know how to solve a problem by \\\n", 478 | "describing the solution in imperative steps \\\n", 479 | "that a machine can easily interpret and you know how to \\\n", 480 | "choose a solution that has a good balance between \\\n", 481 | "time complexity and space complexity. \n", 482 | "\n", 483 | "Here is a question:\n", 484 | "{input}\"\"\"" 485 | ] 486 | }, 487 | { 488 | "cell_type": "code", 489 | "execution_count": 26, 490 | "id": "32a99b89", 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [ 494 | "prompt_infos = [\n", 495 | " {\n", 496 | " \"name\": \"physics\", \n", 497 | " \"description\": \"Good for answering questions about physics\", \n", 498 | " \"prompt_template\": physics_template\n", 499 | " },\n", 500 | " {\n", 501 | " \"name\": \"math\", \n", 502 | " \"description\": \"Good for answering math questions\", \n", 503 | " \"prompt_template\": math_template\n", 504 | " },\n", 505 | " {\n", 506 | " \"name\": \"History\", \n", 507 | " \"description\": \"Good for answering history questions\", \n", 508 | " \"prompt_template\": history_template\n", 509 | " },\n", 510 | " {\n", 511 | " \"name\": \"computer science\", \n", 512 | " \"description\": \"Good for answering computer science questions\", \n", 513 | " \"prompt_template\": computerscience_template\n", 514 | " }\n", 515 | "]" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": 27, 521 | "id": "276b0733", 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [ 525 | "from langchain.chains.router import MultiPromptChain\n", 526 | "from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser\n", 527 | "from langchain.prompts import PromptTemplate" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 28, 533 | "id": "15f71dc1", 534 | "metadata": {}, 535 | "outputs": [], 536 | "source": [ 537 | "llm = ChatOpenAI(temperature=0)" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": 29, 543 | "id": "03a48a6f", 544 | "metadata": {}, 545 | "outputs": [], 546 | "source": [ 547 | "destination_chains = {}\n", 548 | "for p_info in prompt_infos:\n", 549 | " name = p_info[\"name\"]\n", 550 | " prompt_template = p_info[\"prompt_template\"]\n", 551 | " prompt = ChatPromptTemplate.from_template(template=prompt_template)\n", 552 | " chain = LLMChain(llm=llm, prompt=prompt)\n", 553 | " destination_chains[name] = chain \n", 554 | " \n", 555 | "destinations = [f\"{p['name']}: {p['description']}\" for p in prompt_infos]\n", 556 | "destinations_str = \"\\n\".join(destinations)" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": 30, 562 | "id": "636f6469", 563 | "metadata": {}, 564 | "outputs": [], 565 | "source": [ 566 | "default_prompt = ChatPromptTemplate.from_template(\"{input}\")\n", 567 | "default_chain = LLMChain(llm=llm, prompt=default_prompt)" 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": 31, 573 | "id": "bdb06bf3", 574 | "metadata": {}, 575 | "outputs": [], 576 | "source": [ 577 | "MULTI_PROMPT_ROUTER_TEMPLATE = \"\"\"Given a raw text input to a \\\n", 578 | "language model select the model prompt best suited for the input. \\\n", 579 | "You will be given the names of the available prompts and a \\\n", 580 | "description of what the prompt is best suited for. \\\n", 581 | "You may also revise the original input if you think that revising\\\n", 582 | "it will ultimately lead to a better response from the language model.\n", 583 | "\n", 584 | "<< FORMATTING >>\n", 585 | "Return a markdown code snippet with a JSON object formatted to look like:\n", 586 | "```json\n", 587 | "{{{{\n", 588 | " \"destination\": string \\ name of the prompt to use or \"DEFAULT\"\n", 589 | " \"next_inputs\": string \\ a potentially modified version of the original input\n", 590 | "}}}}\n", 591 | "```\n", 592 | "\n", 593 | "REMEMBER: \"destination\" MUST be one of the candidate prompt \\\n", 594 | "names specified below OR it can be \"DEFAULT\" if the input is not\\\n", 595 | "well suited for any of the candidate prompts.\n", 596 | "REMEMBER: \"next_inputs\" can just be the original input \\\n", 597 | "if you don't think any modifications are needed.\n", 598 | "\n", 599 | "<< CANDIDATE PROMPTS >>\n", 600 | "{destinations}\n", 601 | "\n", 602 | "<< INPUT >>\n", 603 | "{{input}}\n", 604 | "\n", 605 | "<< OUTPUT (remember to wrap the output with ```json (output)```)>>\"\"\"" 606 | ] 607 | }, 608 | { 609 | "cell_type": "code", 610 | "execution_count": 32, 611 | "id": "0f0bd1c9", 612 | "metadata": {}, 613 | "outputs": [], 614 | "source": [ 615 | "router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(\n", 616 | " destinations=destinations_str\n", 617 | ")\n", 618 | "router_prompt = PromptTemplate(\n", 619 | " template=router_template,\n", 620 | " input_variables=[\"input\"],\n", 621 | " output_parser=RouterOutputParser(),\n", 622 | ")\n", 623 | "\n", 624 | "router_chain = LLMRouterChain.from_llm(llm, router_prompt)" 625 | ] 626 | }, 627 | { 628 | "cell_type": "code", 629 | "execution_count": 33, 630 | "id": "98d3388d", 631 | "metadata": {}, 632 | "outputs": [], 633 | "source": [ 634 | "chain = MultiPromptChain(router_chain=router_chain, \n", 635 | " destination_chains=destination_chains, \n", 636 | " default_chain=default_chain, verbose=True\n", 637 | " )" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": null, 643 | "id": "7d9a2539", 644 | "metadata": {}, 645 | "outputs": [], 646 | "source": [ 647 | "chain.run(\"What is black body radiation?\")" 648 | ] 649 | }, 650 | { 651 | "cell_type": "code", 652 | "execution_count": null, 653 | "id": "f723333e", 654 | "metadata": {}, 655 | "outputs": [], 656 | "source": [ 657 | "chain.run(\"what is 2 + 2\")" 658 | ] 659 | }, 660 | { 661 | "cell_type": "code", 662 | "execution_count": null, 663 | "id": "464f156f", 664 | "metadata": {}, 665 | "outputs": [], 666 | "source": [ 667 | "chain.run(\"Why does every cell in our body contain DNA?\")" 668 | ] 669 | } 670 | ], 671 | "metadata": { 672 | "kernelspec": { 673 | "display_name": "Python 3 (ipykernel)", 674 | "language": "python", 675 | "name": "python3" 676 | }, 677 | "language_info": { 678 | "codemirror_mode": { 679 | "name": "ipython", 680 | "version": 3 681 | }, 682 | "file_extension": ".py", 683 | "mimetype": "text/x-python", 684 | "name": "python", 685 | "nbconvert_exporter": "python", 686 | "pygments_lexer": "ipython3", 687 | "version": "3.10.9" 688 | } 689 | }, 690 | "nbformat": 4, 691 | "nbformat_minor": 5 692 | } 693 | -------------------------------------------------------------------------------- /L1-Model_prompt_parser.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "4b82a8cc", 6 | "metadata": {}, 7 | "source": [ 8 | "# LangChain: Models, Prompts and Output Parsers\n", 9 | "\n", 10 | "### Outline\n", 11 | "- Direct API calls to OpenAI\n", 12 | "- API calls through LangChain:\n", 13 | " - Prompts\n", 14 | " - Models\n", 15 | " - Output parsers" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 3, 21 | "id": "402d80d3", 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "#!pip install python-dotenv\n", 26 | "#!pip install openai" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 4, 32 | "id": "31d65874", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import os\n", 37 | "import openai\n", 38 | "\n", 39 | "from dotenv import load_dotenv, find_dotenv\n", 40 | "_ = load_dotenv(find_dotenv()) # read local .env file\n", 41 | "openai.api_key = os.environ['OPENAI_API_KEY']" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "9e862117", 47 | "metadata": {}, 48 | "source": [ 49 | "## Chat API : OpenAI\n", 50 | "Let's start with a direct API calls to OpenAI." 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 5, 56 | "id": "707a05a8", 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "def get_completion(prompt, model=\"gpt-3.5-turbo\"):\n", 61 | " messages = [{\"role\": \"user\", \"content\": prompt}]\n", 62 | " response = openai.ChatCompletion.create(\n", 63 | " model=model,\n", 64 | " messages=messages,\n", 65 | " temperature=0, \n", 66 | " )\n", 67 | " return response.choices[0].message[\"content\"]" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 6, 73 | "id": "06af3fda", 74 | "metadata": {}, 75 | "outputs": [ 76 | { 77 | "data": { 78 | "text/plain": [ 79 | "'As an AI language model, I can tell you that the answer to 1+1 is 2.'" 80 | ] 81 | }, 82 | "execution_count": 6, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "get_completion(\"What is 1+1?\")" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 7, 94 | "id": "e31a9c46", 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "customer_email = \"\"\"\n", 99 | "Arrr, I be fuming that me blender lid \\\n", 100 | "flew off and splattered me kitchen walls \\\n", 101 | "with smoothie! And to make matters worse,\\\n", 102 | "the warranty don't cover the cost of \\\n", 103 | "cleaning up me kitchen. I need yer help \\\n", 104 | "right now, matey!\n", 105 | "\"\"\"" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 8, 111 | "id": "b88783a2", 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "style = \"\"\"American English \\\n", 116 | "in a calm and respectful tone\n", 117 | "\"\"\"" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 9, 123 | "id": "36553451", 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "Translate the text that is delimited by triple backticks \n", 131 | "into a style that is American English in a calm and respectful tone\n", 132 | ".\n", 133 | "text: ```\n", 134 | "Arrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse,the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!\n", 135 | "```\n", 136 | "\n" 137 | ] 138 | } 139 | ], 140 | "source": [ 141 | "prompt = f\"\"\"Translate the text \\\n", 142 | "that is delimited by triple backticks \n", 143 | "into a style that is {style}.\n", 144 | "text: ```{customer_email}```\n", 145 | "\"\"\"\n", 146 | "\n", 147 | "print(prompt)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 10, 153 | "id": "16d5af8a", 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "response = get_completion(prompt)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 11, 163 | "id": "1518fa57", 164 | "metadata": {}, 165 | "outputs": [ 166 | { 167 | "data": { 168 | "text/plain": [ 169 | "'I am quite upset that my blender lid came off and caused my smoothie to splatter all over my kitchen walls. Additionally, the warranty does not cover the cost of cleaning up the mess. Would you be able to assist me, please? Thank you kindly.'" 170 | ] 171 | }, 172 | "execution_count": 11, 173 | "metadata": {}, 174 | "output_type": "execute_result" 175 | } 176 | ], 177 | "source": [ 178 | "response" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "id": "06c9ccdb", 184 | "metadata": {}, 185 | "source": [ 186 | "## Chat API : LangChain\n", 187 | "Let's try how we can do the same thing using LangChain" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 13, 193 | "id": "76051063", 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "#!pip install --upgrade langchain" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "id": "115538b0", 203 | "metadata": {}, 204 | "source": [ 205 | "### Model " 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 14, 211 | "id": "052942e3", 212 | "metadata": {}, 213 | "outputs": [], 214 | "source": [ 215 | "from langchain.chat_models import ChatOpenAI" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "id": "10768b74", 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "# To control the randomness and creativity of the generated\n", 226 | "# text by an LLM, use temperature = 0.0\n", 227 | "chat = ChatOpenAI(temperature=0.0)\n", 228 | "chat" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "id": "43605a73", 234 | "metadata": {}, 235 | "source": [ 236 | "### Prompt template" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 16, 242 | "id": "303f8552", 243 | "metadata": {}, 244 | "outputs": [], 245 | "source": [ 246 | "template_string = \"\"\"Translate the text \\\n", 247 | "that is delimited by triple backticks \\\n", 248 | "into a style that is {style}. \\\n", 249 | "text: ```{text}```\n", 250 | "\"\"\"" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 17, 256 | "id": "034fcf65", 257 | "metadata": {}, 258 | "outputs": [], 259 | "source": [ 260 | "from langchain.prompts import ChatPromptTemplate\n", 261 | "prompt_template = ChatPromptTemplate.from_template(template_string)" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": 23, 267 | "id": "3d68adac", 268 | "metadata": {}, 269 | "outputs": [ 270 | { 271 | "data": { 272 | "text/plain": [ 273 | "PromptTemplate(input_variables=['style', 'text'], output_parser=None, partial_variables={}, template='Translate the text that is delimited by triple backticks into a style that is {style}. text: ```{text}```\\n', template_format='f-string', validate_template=True)" 274 | ] 275 | }, 276 | "execution_count": 23, 277 | "metadata": {}, 278 | "output_type": "execute_result" 279 | } 280 | ], 281 | "source": [ 282 | "prompt_template.messages[0].prompt" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": 24, 288 | "id": "e9d5897f", 289 | "metadata": {}, 290 | "outputs": [ 291 | { 292 | "data": { 293 | "text/plain": [ 294 | "['style', 'text']" 295 | ] 296 | }, 297 | "execution_count": 24, 298 | "metadata": {}, 299 | "output_type": "execute_result" 300 | } 301 | ], 302 | "source": [ 303 | "prompt_template.messages[0].prompt.input_variables" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 25, 309 | "id": "d71976ae", 310 | "metadata": {}, 311 | "outputs": [], 312 | "source": [ 313 | "customer_style = \"\"\"American English \\\n", 314 | "in a calm and respectful tone\n", 315 | "\"\"\"" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": 26, 321 | "id": "1e77bad7", 322 | "metadata": {}, 323 | "outputs": [], 324 | "source": [ 325 | "customer_email = \"\"\"\n", 326 | "Arrr, I be fuming that me blender lid \\\n", 327 | "flew off and splattered me kitchen walls \\\n", 328 | "with smoothie! And to make matters worse, \\\n", 329 | "the warranty don't cover the cost of \\\n", 330 | "cleaning up me kitchen. I need yer help \\\n", 331 | "right now, matey!\n", 332 | "\"\"\"" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 27, 338 | "id": "2031255a", 339 | "metadata": {}, 340 | "outputs": [], 341 | "source": [ 342 | "customer_messages = prompt_template.format_messages(\n", 343 | " style=customer_style,\n", 344 | " text=customer_email)" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 31, 350 | "id": "b53982ca", 351 | "metadata": {}, 352 | "outputs": [ 353 | { 354 | "name": "stdout", 355 | "output_type": "stream", 356 | "text": [ 357 | "\n", 358 | "\n" 359 | ] 360 | } 361 | ], 362 | "source": [ 363 | "print(type(customer_messages))\n", 364 | "print(type(customer_messages[0]))" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 33, 370 | "id": "b1fc2014", 371 | "metadata": {}, 372 | "outputs": [ 373 | { 374 | "name": "stdout", 375 | "output_type": "stream", 376 | "text": [ 377 | "content=\"Translate the text that is delimited by triple backticks into a style that is American English in a calm and respectful tone\\n. text: ```\\nArrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse, the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!\\n```\\n\" additional_kwargs={} example=False\n" 378 | ] 379 | } 380 | ], 381 | "source": [ 382 | "# Prompt expected by the user \n", 383 | "print(customer_messages[0])" 384 | ] 385 | }, 386 | { 387 | "cell_type": "code", 388 | "execution_count": 37, 389 | "id": "b494db21", 390 | "metadata": {}, 391 | "outputs": [], 392 | "source": [ 393 | "# Call the LLM to translate to the style of the customer message\n", 394 | "# Reference: chat = ChatOpenAI(temperature=0.0)\n", 395 | "customer_response = chat(customer_messages)" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 38, 401 | "id": "3f503d87", 402 | "metadata": {}, 403 | "outputs": [ 404 | { 405 | "name": "stdout", 406 | "output_type": "stream", 407 | "text": [ 408 | "I'm really frustrated that my blender lid flew off and made a mess of my kitchen walls with smoothie. To add to my frustration, the warranty doesn't cover the cost of cleaning up my kitchen. Can you please help me out, friend?\n" 409 | ] 410 | } 411 | ], 412 | "source": [ 413 | "print(customer_response.content)" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": 40, 419 | "id": "9379d3fe", 420 | "metadata": {}, 421 | "outputs": [], 422 | "source": [ 423 | "service_reply = \"\"\"Hey there customer, \\\n", 424 | "the warranty does not cover \\\n", 425 | "cleaning expenses for your kitchen \\\n", 426 | "because it's your fault that \\\n", 427 | "you misused your blender \\\n", 428 | "by forgetting to put the lid on before \\\n", 429 | "starting the blender. \\\n", 430 | "Tough luck! See ya!\n", 431 | "\"\"\"" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 41, 437 | "id": "b01033b4", 438 | "metadata": {}, 439 | "outputs": [], 440 | "source": [ 441 | "service_style_pirate = \"\"\"\\\n", 442 | "a polite tone \\\n", 443 | "that speaks in English Pirate\\\n", 444 | "\"\"\"" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 42, 450 | "id": "fffe37fc", 451 | "metadata": {}, 452 | "outputs": [ 453 | { 454 | "name": "stdout", 455 | "output_type": "stream", 456 | "text": [ 457 | "Translate the text that is delimited by triple backticks into a style that is a polite tone that speaks in English Pirate. text: ```Hey there customer, the warranty does not cover cleaning expenses for your kitchen because it's your fault that you misused your blender by forgetting to put the lid on before starting the blender. Tough luck! See ya!\n", 458 | "```\n", 459 | "\n" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "service_messages = prompt_template.format_messages(\n", 465 | " style=service_style_pirate,\n", 466 | " text=service_reply)\n", 467 | "\n", 468 | "print(service_messages[0].content)" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": 43, 474 | "id": "f7a6289e", 475 | "metadata": {}, 476 | "outputs": [ 477 | { 478 | "name": "stdout", 479 | "output_type": "stream", 480 | "text": [ 481 | "Ahoy there, matey! I must kindly inform ye that the warranty be not coverin' the expenses o' cleaning yer galley, as 'tis yer own fault fer misusin' yer blender by forgettin' to put the lid on afore startin' it. Aye, tough luck! Farewell and may the winds be in yer favor!\n" 482 | ] 483 | } 484 | ], 485 | "source": [ 486 | "service_response = chat(service_messages)\n", 487 | "print(service_response.content)" 488 | ] 489 | }, 490 | { 491 | "cell_type": "markdown", 492 | "id": "f6439706", 493 | "metadata": {}, 494 | "source": [ 495 | "## Output Parsers\n", 496 | "Let's start with defining how we would like the LLM output to look like:" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": 44, 502 | "id": "59aa3c40", 503 | "metadata": {}, 504 | "outputs": [ 505 | { 506 | "data": { 507 | "text/plain": [ 508 | "{'gift': False, 'delivery_days': 5, 'price_value': 'pretty affordable!'}" 509 | ] 510 | }, 511 | "execution_count": 44, 512 | "metadata": {}, 513 | "output_type": "execute_result" 514 | } 515 | ], 516 | "source": [ 517 | "{\n", 518 | " \"gift\": False,\n", 519 | " \"delivery_days\": 5,\n", 520 | " \"price_value\": \"pretty affordable!\"\n", 521 | "}" 522 | ] 523 | }, 524 | { 525 | "cell_type": "code", 526 | "execution_count": 45, 527 | "id": "02fb0334", 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [ 531 | "customer_review = \"\"\"\\\n", 532 | "This leaf blower is pretty amazing. It has four settings:\\\n", 533 | "candle blower, gentle breeze, windy city, and tornado. \\\n", 534 | "It arrived in two days, just in time for my wife's \\\n", 535 | "anniversary present. \\\n", 536 | "I think my wife liked it so much she was speechless. \\\n", 537 | "So far I've been the only one using it, and I've been \\\n", 538 | "using it every other morning to clear the leaves on our lawn. \\\n", 539 | "It's slightly more expensive than the other leaf blowers \\\n", 540 | "out there, but I think it's worth it for the extra features.\n", 541 | "\"\"\"\n", 542 | "\n", 543 | "review_template = \"\"\"\\\n", 544 | "For the following text, extract the following information:\n", 545 | "\n", 546 | "gift: Was the item purchased as a gift for someone else? \\\n", 547 | "Answer True if yes, False if not or unknown.\n", 548 | "\n", 549 | "delivery_days: How many days did it take for the product \\\n", 550 | "to arrive? If this information is not found, output -1.\n", 551 | "\n", 552 | "price_value: Extract any sentences about the value or price,\\\n", 553 | "and output them as a comma separated Python list.\n", 554 | "\n", 555 | "Format the output as JSON with the following keys:\n", 556 | "gift\n", 557 | "delivery_days\n", 558 | "price_value\n", 559 | "\n", 560 | "text: {text}\n", 561 | "\"\"\"" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 46, 567 | "id": "752c2ef6", 568 | "metadata": {}, 569 | "outputs": [ 570 | { 571 | "name": "stdout", 572 | "output_type": "stream", 573 | "text": [ 574 | "input_variables=['text'] output_parser=None partial_variables={} messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['text'], output_parser=None, partial_variables={}, template='For the following text, extract the following information:\\n\\ngift: Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.\\n\\ndelivery_days: How many days did it take for the product to arrive? If this information is not found, output -1.\\n\\nprice_value: Extract any sentences about the value or price,and output them as a comma separated Python list.\\n\\nFormat the output as JSON with the following keys:\\ngift\\ndelivery_days\\nprice_value\\n\\ntext: {text}\\n', template_format='f-string', validate_template=True), additional_kwargs={})]\n" 575 | ] 576 | } 577 | ], 578 | "source": [ 579 | "from langchain.prompts import ChatPromptTemplate\n", 580 | "\n", 581 | "prompt_template = ChatPromptTemplate.from_template(review_template)\n", 582 | "print(prompt_template)" 583 | ] 584 | }, 585 | { 586 | "cell_type": "code", 587 | "execution_count": 47, 588 | "id": "2fd4e31d", 589 | "metadata": {}, 590 | "outputs": [ 591 | { 592 | "name": "stdout", 593 | "output_type": "stream", 594 | "text": [ 595 | "{\n", 596 | " \"gift\": true,\n", 597 | " \"delivery_days\": 2,\n", 598 | " \"price_value\": [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]\n", 599 | "}\n" 600 | ] 601 | } 602 | ], 603 | "source": [ 604 | "messages = prompt_template.format_messages(text=customer_review)\n", 605 | "chat = ChatOpenAI(temperature=0.0)\n", 606 | "response = chat(messages)\n", 607 | "print(response.content)" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": 48, 613 | "id": "f8d3b552", 614 | "metadata": {}, 615 | "outputs": [ 616 | { 617 | "data": { 618 | "text/plain": [ 619 | "str" 620 | ] 621 | }, 622 | "execution_count": 48, 623 | "metadata": {}, 624 | "output_type": "execute_result" 625 | } 626 | ], 627 | "source": [ 628 | "type(response.content)" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "execution_count": 49, 634 | "id": "a5e7784c", 635 | "metadata": {}, 636 | "outputs": [ 637 | { 638 | "ename": "AttributeError", 639 | "evalue": "'str' object has no attribute 'get'", 640 | "output_type": "error", 641 | "traceback": [ 642 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 643 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", 644 | "Cell \u001b[0;32mIn[49], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# You will get an error by running this line of code \u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# because'gift' is not a dictionary\u001b[39;00m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m# 'gift' is a string\u001b[39;00m\n\u001b[0;32m----> 4\u001b[0m \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcontent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mgift\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", 645 | "\u001b[0;31mAttributeError\u001b[0m: 'str' object has no attribute 'get'" 646 | ] 647 | } 648 | ], 649 | "source": [ 650 | "# You will get an error by running this line of code \n", 651 | "# because'gift' is not a dictionary\n", 652 | "# 'gift' is a string\n", 653 | "response.content.get('gift')" 654 | ] 655 | }, 656 | { 657 | "cell_type": "markdown", 658 | "id": "e057b5d8", 659 | "metadata": {}, 660 | "source": [ 661 | "## Parse the LLM output string into a Python dictionary" 662 | ] 663 | }, 664 | { 665 | "cell_type": "code", 666 | "execution_count": 50, 667 | "id": "4f44204b", 668 | "metadata": {}, 669 | "outputs": [], 670 | "source": [ 671 | "from langchain.output_parsers import ResponseSchema\n", 672 | "from langchain.output_parsers import StructuredOutputParser" 673 | ] 674 | }, 675 | { 676 | "cell_type": "code", 677 | "execution_count": 51, 678 | "id": "8959253b", 679 | "metadata": {}, 680 | "outputs": [], 681 | "source": [ 682 | "gift_schema = ResponseSchema(name=\"gift\",\n", 683 | " description=\"Was the item purchased\\\n", 684 | " as a gift for someone else? \\\n", 685 | " Answer True if yes,\\\n", 686 | " False if not or unknown.\")\n", 687 | "delivery_days_schema = ResponseSchema(name=\"delivery_days\",\n", 688 | " description=\"How many days\\\n", 689 | " did it take for the product\\\n", 690 | " to arrive? If this \\\n", 691 | " information is not found,\\\n", 692 | " output -1.\")\n", 693 | "price_value_schema = ResponseSchema(name=\"price_value\",\n", 694 | " description=\"Extract any\\\n", 695 | " sentences about the value or \\\n", 696 | " price, and output them as a \\\n", 697 | " comma separated Python list.\")\n", 698 | "\n", 699 | "response_schemas = [gift_schema, \n", 700 | " delivery_days_schema,\n", 701 | " price_value_schema]" 702 | ] 703 | }, 704 | { 705 | "cell_type": "code", 706 | "execution_count": 52, 707 | "id": "5f08884e", 708 | "metadata": {}, 709 | "outputs": [], 710 | "source": [ 711 | "output_parser = StructuredOutputParser.from_response_schemas(response_schemas)" 712 | ] 713 | }, 714 | { 715 | "cell_type": "code", 716 | "execution_count": 57, 717 | "id": "538b9f84", 718 | "metadata": {}, 719 | "outputs": [ 720 | { 721 | "name": "stdout", 722 | "output_type": "stream", 723 | "text": [ 724 | "response_schemas=[ResponseSchema(name='gift', description='Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.', type='string'), ResponseSchema(name='delivery_days', description='How many days did it take for the product to arrive? If this information is not found, output -1.', type='string'), ResponseSchema(name='price_value', description='Extract any sentences about the value or price, and output them as a comma separated Python list.', type='string')]\n" 725 | ] 726 | } 727 | ], 728 | "source": [ 729 | "print(output_parser)" 730 | ] 731 | }, 732 | { 733 | "cell_type": "code", 734 | "execution_count": 54, 735 | "id": "6ff98702", 736 | "metadata": {}, 737 | "outputs": [], 738 | "source": [ 739 | "format_instructions = output_parser.get_format_instructions()" 740 | ] 741 | }, 742 | { 743 | "cell_type": "code", 744 | "execution_count": 56, 745 | "id": "ceb0b416", 746 | "metadata": {}, 747 | "outputs": [ 748 | { 749 | "name": "stdout", 750 | "output_type": "stream", 751 | "text": [ 752 | "The output should be a markdown code snippet formatted in the following schema, including the leading and trailing \"```json\" and \"```\":\n", 753 | "\n", 754 | "```json\n", 755 | "{\n", 756 | "\t\"gift\": string // Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.\n", 757 | "\t\"delivery_days\": string // How many days did it take for the product to arrive? If this information is not found, output -1.\n", 758 | "\t\"price_value\": string // Extract any sentences about the value or price, and output them as a comma separated Python list.\n", 759 | "}\n", 760 | "```\n" 761 | ] 762 | } 763 | ], 764 | "source": [ 765 | "print(format_instructions)" 766 | ] 767 | }, 768 | { 769 | "cell_type": "code", 770 | "execution_count": 58, 771 | "id": "ecb4b006", 772 | "metadata": {}, 773 | "outputs": [], 774 | "source": [ 775 | "review_template_2 = \"\"\"\\\n", 776 | "For the following text, extract the following information:\n", 777 | "\n", 778 | "gift: Was the item purchased as a gift for someone else? \\\n", 779 | "Answer True if yes, False if not or unknown.\n", 780 | "\n", 781 | "delivery_days: How many days did it take for the product\\\n", 782 | "to arrive? If this information is not found, output -1.\n", 783 | "\n", 784 | "price_value: Extract any sentences about the value or price,\\\n", 785 | "and output them as a comma separated Python list.\n", 786 | "\n", 787 | "text: {text}\n", 788 | "\n", 789 | "{format_instructions}\n", 790 | "\"\"\"\n", 791 | "\n", 792 | "prompt = ChatPromptTemplate.from_template(template=review_template_2)\n", 793 | "\n", 794 | "messages = prompt.format_messages(text=customer_review, \n", 795 | " format_instructions=format_instructions)" 796 | ] 797 | }, 798 | { 799 | "cell_type": "code", 800 | "execution_count": 59, 801 | "id": "77123bd1", 802 | "metadata": {}, 803 | "outputs": [ 804 | { 805 | "name": "stdout", 806 | "output_type": "stream", 807 | "text": [ 808 | "For the following text, extract the following information:\n", 809 | "\n", 810 | "gift: Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.\n", 811 | "\n", 812 | "delivery_days: How many days did it take for the productto arrive? If this information is not found, output -1.\n", 813 | "\n", 814 | "price_value: Extract any sentences about the value or price,and output them as a comma separated Python list.\n", 815 | "\n", 816 | "text: This leaf blower is pretty amazing. It has four settings:candle blower, gentle breeze, windy city, and tornado. It arrived in two days, just in time for my wife's anniversary present. I think my wife liked it so much she was speechless. So far I've been the only one using it, and I've been using it every other morning to clear the leaves on our lawn. It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\n", 817 | "\n", 818 | "\n", 819 | "The output should be a markdown code snippet formatted in the following schema, including the leading and trailing \"```json\" and \"```\":\n", 820 | "\n", 821 | "```json\n", 822 | "{\n", 823 | "\t\"gift\": string // Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.\n", 824 | "\t\"delivery_days\": string // How many days did it take for the product to arrive? If this information is not found, output -1.\n", 825 | "\t\"price_value\": string // Extract any sentences about the value or price, and output them as a comma separated Python list.\n", 826 | "}\n", 827 | "```\n", 828 | "\n" 829 | ] 830 | } 831 | ], 832 | "source": [ 833 | "print(messages[0].content)" 834 | ] 835 | }, 836 | { 837 | "cell_type": "code", 838 | "execution_count": 60, 839 | "id": "790ec088", 840 | "metadata": {}, 841 | "outputs": [], 842 | "source": [ 843 | "response = chat(messages)" 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | "execution_count": 61, 849 | "id": "5b6687b6", 850 | "metadata": {}, 851 | "outputs": [ 852 | { 853 | "name": "stdout", 854 | "output_type": "stream", 855 | "text": [ 856 | "```json\n", 857 | "{\n", 858 | "\t\"gift\": true,\n", 859 | "\t\"delivery_days\": \"2\",\n", 860 | "\t\"price_value\": [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]\n", 861 | "}\n", 862 | "```\n" 863 | ] 864 | } 865 | ], 866 | "source": [ 867 | "print(response.content)" 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "execution_count": 62, 873 | "id": "91ad9d28", 874 | "metadata": {}, 875 | "outputs": [], 876 | "source": [ 877 | "output_dict = output_parser.parse(response.content)" 878 | ] 879 | }, 880 | { 881 | "cell_type": "code", 882 | "execution_count": 63, 883 | "id": "582d2493", 884 | "metadata": {}, 885 | "outputs": [ 886 | { 887 | "data": { 888 | "text/plain": [ 889 | "{'gift': True,\n", 890 | " 'delivery_days': '2',\n", 891 | " 'price_value': [\"It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.\"]}" 892 | ] 893 | }, 894 | "execution_count": 63, 895 | "metadata": {}, 896 | "output_type": "execute_result" 897 | } 898 | ], 899 | "source": [ 900 | "output_dict" 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": 64, 906 | "id": "5f711b93", 907 | "metadata": {}, 908 | "outputs": [ 909 | { 910 | "data": { 911 | "text/plain": [ 912 | "dict" 913 | ] 914 | }, 915 | "execution_count": 64, 916 | "metadata": {}, 917 | "output_type": "execute_result" 918 | } 919 | ], 920 | "source": [ 921 | "type(output_dict)" 922 | ] 923 | }, 924 | { 925 | "cell_type": "code", 926 | "execution_count": 65, 927 | "id": "aeb5b03b", 928 | "metadata": {}, 929 | "outputs": [ 930 | { 931 | "data": { 932 | "text/plain": [ 933 | "'2'" 934 | ] 935 | }, 936 | "execution_count": 65, 937 | "metadata": {}, 938 | "output_type": "execute_result" 939 | } 940 | ], 941 | "source": [ 942 | "output_dict.get('delivery_days')" 943 | ] 944 | }, 945 | { 946 | "cell_type": "code", 947 | "execution_count": null, 948 | "id": "6e02b8ae", 949 | "metadata": {}, 950 | "outputs": [], 951 | "source": [] 952 | } 953 | ], 954 | "metadata": { 955 | "kernelspec": { 956 | "display_name": "Python 3 (ipykernel)", 957 | "language": "python", 958 | "name": "python3" 959 | }, 960 | "language_info": { 961 | "codemirror_mode": { 962 | "name": "ipython", 963 | "version": 3 964 | }, 965 | "file_extension": ".py", 966 | "mimetype": "text/x-python", 967 | "name": "python", 968 | "nbconvert_exporter": "python", 969 | "pygments_lexer": "ipython3", 970 | "version": "3.10.9" 971 | } 972 | }, 973 | "nbformat": 4, 974 | "nbformat_minor": 5 975 | } 976 | --------------------------------------------------------------------------------