├── .gitignore
├── 1. Generative Models.ipynb
├── 2. LangChain.ipynb
├── 3. Information Processing.ipynb
├── 4. ChatBots.ipynb
├── 5. Prompt Engineering.ipynb
├── LICENSE
├── README.md
├── d4sci.mplstyle
├── data
├── D4Sci_logo_ball.png
├── D4Sci_logo_full.png
├── Northwind_small.sqlite
└── trump.csv
├── images
└── ducky.png
├── requirements.txt
└── slides
└── LangChain.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | cache/
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | pip-wheel-metadata/
26 | share/python-wheels/
27 | *.egg-info/
28 | .installed.cfg
29 | *.egg
30 | MANIFEST
31 |
32 | # PyInstaller
33 | # Usually these files are written by a python script from a template
34 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
35 | *.manifest
36 | *.spec
37 |
38 | # Installer logs
39 | pip-log.txt
40 | pip-delete-this-directory.txt
41 |
42 | # Unit test / coverage reports
43 | htmlcov/
44 | .tox/
45 | .nox/
46 | .coverage
47 | .coverage.*
48 | .cache
49 | nosetests.xml
50 | coverage.xml
51 | *.cover
52 | *.py,cover
53 | .hypothesis/
54 | .pytest_cache/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
77 | target/
78 |
79 | # Jupyter Notebook
80 | .ipynb_checkpoints
81 |
82 | # IPython
83 | profile_default/
84 | ipython_config.py
85 |
86 | # pyenv
87 | .python-version
88 |
89 | # pipenv
90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
93 | # install all needed dependencies.
94 | #Pipfile.lock
95 |
96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97 | __pypackages__/
98 |
99 | # Celery stuff
100 | celerybeat-schedule
101 | celerybeat.pid
102 |
103 | # SageMath parsed files
104 | *.sage.py
105 |
106 | # Environments
107 | .env
108 | .venv
109 | env/
110 | venv/
111 | ENV/
112 | env.bak/
113 | venv.bak/
114 |
115 | # Spyder project settings
116 | .spyderproject
117 | .spyproject
118 |
119 | # Rope project settings
120 | .ropeproject
121 |
122 | # mkdocs documentation
123 | /site
124 |
125 | # mypy
126 | .mypy_cache/
127 | .dmypy.json
128 | dmypy.json
129 |
130 | # Pyre type checker
131 | .pyre/
132 |
--------------------------------------------------------------------------------
/2. LangChain.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "
\n",
8 | "
\n",
9 | "
LangChain for Generative AI
\n",
10 | "
LangChain
\n",
11 | "
Bruno Gonçalves
\n",
12 | " www.data4sci.com
\n",
13 | " @bgoncalves, @data4sci
\n",
14 | "
"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from collections import Counter\n",
24 | "from pprint import pprint\n",
25 | "from operator import itemgetter\n",
26 | "\n",
27 | "import pandas as pd\n",
28 | "import numpy as np\n",
29 | "import matplotlib.pyplot as plt \n",
30 | "\n",
31 | "import torch\n",
32 | "\n",
33 | "import openai\n",
34 | "from openai import OpenAI\n",
35 | "\n",
36 | "import transformers\n",
37 | "from transformers import pipeline\n",
38 | "from transformers import set_seed\n",
39 | "set_seed(42) # Set the seed to get reproducible results\n",
40 | "\n",
41 | "\n",
42 | "import langchain\n",
43 | "from langchain.chains import create_sql_query_chain\n",
44 | "from langchain.tools import DuckDuckGoSearchRun\n",
45 | "\n",
46 | "import langchain_openai\n",
47 | "from langchain_openai import ChatOpenAI\n",
48 | "\n",
49 | "import langchain_anthropic\n",
50 | "from langchain_anthropic import ChatAnthropic\n",
51 | "\n",
52 | "import langchain_core\n",
53 | "from langchain_core.messages import HumanMessage, SystemMessage\n",
54 | "from langchain_core.output_parsers import StrOutputParser\n",
55 | "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate\n",
56 | "from langchain_core.chat_history import BaseChatMessageHistory\n",
57 | "from langchain_core.runnables.history import RunnableWithMessageHistory\n",
58 | "from langchain_core.runnables import RunnablePassthrough\n",
59 | "\n",
60 | "import langchain_community\n",
61 | "from langchain_community.chat_message_histories import ChatMessageHistory\n",
62 | "from langchain_community.utilities import SQLDatabase\n",
63 | "from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool\n",
64 | "\n",
65 | "import watermark\n",
66 | "\n",
67 | "%load_ext watermark\n",
68 | "%matplotlib inline"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "We start by print out the versions of the libraries we're using for future reference"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": 2,
81 | "metadata": {},
82 | "outputs": [
83 | {
84 | "name": "stdout",
85 | "output_type": "stream",
86 | "text": [
87 | "Python implementation: CPython\n",
88 | "Python version : 3.11.7\n",
89 | "IPython version : 8.12.3\n",
90 | "\n",
91 | "Compiler : Clang 14.0.6 \n",
92 | "OS : Darwin\n",
93 | "Release : 23.6.0\n",
94 | "Machine : arm64\n",
95 | "Processor : arm\n",
96 | "CPU cores : 16\n",
97 | "Architecture: 64bit\n",
98 | "\n",
99 | "Git hash: 0b932bf32c4e9b1e4ff9126fc7e8e7ac7b4205ff\n",
100 | "\n",
101 | "langchain_core : 0.2.3\n",
102 | "langchain_openai : 0.1.8\n",
103 | "transformers : 4.41.1\n",
104 | "langchain : 0.2.2\n",
105 | "langchain_anthropic: 0.1.15\n",
106 | "pandas : 2.2.3\n",
107 | "langchain_community: 0.2.1\n",
108 | "torch : 2.3.0\n",
109 | "watermark : 2.4.3\n",
110 | "matplotlib : 3.8.0\n",
111 | "openai : 1.30.5\n",
112 | "numpy : 1.26.4\n",
113 | "\n"
114 | ]
115 | }
116 | ],
117 | "source": [
118 | "%watermark -n -v -m -g -iv"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "Load default figure style"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": 3,
131 | "metadata": {},
132 | "outputs": [],
133 | "source": [
134 | "plt.style.use('./d4sci.mplstyle')"
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "metadata": {},
140 | "source": [
141 | "# OpenAI"
142 | ]
143 | },
144 | {
145 | "cell_type": "markdown",
146 | "metadata": {},
147 | "source": [
148 | "The first step is generate API key on the OpenAI website and store it as the \"OPENAI_API_KEY\" variable in your local environment. Without it we won't be able to do anything. You can find your API key in your using settings: https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key. Then we are ready to instantiate the client"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": 4,
154 | "metadata": {},
155 | "outputs": [],
156 | "source": [
157 | "client = OpenAI()"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 5,
163 | "metadata": {},
164 | "outputs": [],
165 | "source": [
166 | "response = client.chat.completions.create(\n",
167 | " model=\"gpt-4o\",\n",
168 | " messages=[\n",
169 | " {\n",
170 | " \"role\": \"user\", \n",
171 | " \"content\": \"What was Superman's weakness?\"\n",
172 | " },\n",
173 | " ]\n",
174 | ")"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 6,
180 | "metadata": {},
181 | "outputs": [
182 | {
183 | "name": "stdout",
184 | "output_type": "stream",
185 | "text": [
186 | "ChatCompletion(id='chatcmpl-AVlBKZ3AK1ebP607ObfRLejPGembN', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content=\"Superman's most well-known weakness is kryptonite, a mineral from his home planet of Krypton. Exposure to kryptonite weakens Superman and can potentially be fatal to him. Different forms of kryptonite have varied effects; for example, green kryptonite weakens him, while red kryptonite can cause unpredictable, often bizarre changes in his behavior and powers. Besides kryptonite, Superman is also vulnerable to magic, which can affect him just as it would any other being. Additionally, he's not immune to the effects of a red sun, which can drain him of his powers.\", role='assistant', function_call=None, tool_calls=None, refusal=None))], created=1732132898, model='gpt-4o-2024-08-06', object='chat.completion', system_fingerprint='fp_7f6be3efb0', usage=CompletionUsage(completion_tokens=115, prompt_tokens=13, total_tokens=128, prompt_tokens_details={'cached_tokens': 0, 'audio_tokens': 0}, completion_tokens_details={'reasoning_tokens': 0, 'audio_tokens': 0, 'accepted_prediction_tokens': 0, 'rejected_prediction_tokens': 0}))\n"
187 | ]
188 | }
189 | ],
190 | "source": [
191 | "print(response)"
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": 7,
197 | "metadata": {},
198 | "outputs": [
199 | {
200 | "name": "stdout",
201 | "output_type": "stream",
202 | "text": [
203 | "Superman's most well-known weakness is kryptonite, a mineral from his home planet of Krypton. Exposure to kryptonite weakens Superman and can potentially be fatal to him. Different forms of kryptonite have varied effects; for example, green kryptonite weakens him, while red kryptonite can cause unpredictable, often bizarre changes in his behavior and powers. Besides kryptonite, Superman is also vulnerable to magic, which can affect him just as it would any other being. Additionally, he's not immune to the effects of a red sun, which can drain him of his powers.\n"
204 | ]
205 | }
206 | ],
207 | "source": [
208 | "print(response.choices[0].message.content)"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "# LangChain"
216 | ]
217 | },
218 | {
219 | "cell_type": "markdown",
220 | "metadata": {},
221 | "source": [
222 | "We instantiate the LangChain interface for OpenAI"
223 | ]
224 | },
225 | {
226 | "cell_type": "code",
227 | "execution_count": 8,
228 | "metadata": {},
229 | "outputs": [],
230 | "source": [
231 | "model = ChatOpenAI(model=\"gpt-4o\")"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": 9,
237 | "metadata": {},
238 | "outputs": [
239 | {
240 | "name": "stdout",
241 | "output_type": "stream",
242 | "text": [
243 | "content=\"Superman's primary weakness is Kryptonite, a mineral from his home planet of Krypton. When exposed to Kryptonite, Superman's powers are significantly weakened, and prolonged exposure can be fatal to him. There are different types of Kryptonite, with green Kryptonite being the most common and harmful to Superman. Other versions, like red, blue, and gold Kryptonite, have varying effects, often altering his powers or behavior in unpredictable ways.\\n\\nIn addition to Kryptonite, Superman is also vulnerable to magic. His powers, which are based on Earth's yellow sun, do not protect him from magical attacks or spells. Furthermore, Superman's moral code and compassion for others are often considered weaknesses, as his enemies can exploit these traits to manipulate or distract him.\" response_metadata={'token_usage': {'completion_tokens': 150, 'prompt_tokens': 13, 'total_tokens': 163, 'prompt_tokens_details': {'cached_tokens': 0, 'audio_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0, 'audio_tokens': 0, 'accepted_prediction_tokens': 0, 'rejected_prediction_tokens': 0}}, 'model_name': 'gpt-4o', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'stop', 'logprobs': None} id='run-3ef83ee5-4b56-4bb1-abae-2cbfdb3d5539-0' usage_metadata={'input_tokens': 13, 'output_tokens': 150, 'total_tokens': 163}\n"
244 | ]
245 | }
246 | ],
247 | "source": [
248 | "messages = [\n",
249 | " SystemMessage(content=\"What was Superman's weakness?\"),\n",
250 | "]\n",
251 | "\n",
252 | "output = model.invoke(messages)\n",
253 | "print(output)"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": 10,
259 | "metadata": {},
260 | "outputs": [
261 | {
262 | "data": {
263 | "text/plain": [
264 | "{'completion_tokens': 150,\n",
265 | " 'prompt_tokens': 13,\n",
266 | " 'total_tokens': 163,\n",
267 | " 'prompt_tokens_details': {'cached_tokens': 0, 'audio_tokens': 0},\n",
268 | " 'completion_tokens_details': {'reasoning_tokens': 0,\n",
269 | " 'audio_tokens': 0,\n",
270 | " 'accepted_prediction_tokens': 0,\n",
271 | " 'rejected_prediction_tokens': 0}}"
272 | ]
273 | },
274 | "execution_count": 10,
275 | "metadata": {},
276 | "output_type": "execute_result"
277 | }
278 | ],
279 | "source": [
280 | "output.response_metadata[\"token_usage\"]"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": 11,
286 | "metadata": {},
287 | "outputs": [],
288 | "source": [
289 | "parser = StrOutputParser()"
290 | ]
291 | },
292 | {
293 | "cell_type": "code",
294 | "execution_count": 12,
295 | "metadata": {},
296 | "outputs": [],
297 | "source": [
298 | "result = model.invoke(messages)"
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "execution_count": 13,
304 | "metadata": {},
305 | "outputs": [
306 | {
307 | "data": {
308 | "text/plain": [
309 | "'Superman\\'s most well-known weakness is Kryptonite, a mineral from his home planet of Krypton. When exposed to it, Superman loses his powers and becomes vulnerable, and prolonged exposure can be fatal. Different forms of Kryptonite have different effects, but green Kryptonite is the most common and harmful to him.\\n\\nAdditionally, Superman is vulnerable to magic and can be harmed by magical spells and artifacts. While not a \"weakness\" in the traditional sense, his powers don\\'t protect him from magical attacks as they do against conventional threats.\\n\\nLastly, Superman\\'s compassion and strong moral code can sometimes be seen as a weakness, as his enemies may exploit his desire to protect others to manipulate or trap him.'"
310 | ]
311 | },
312 | "execution_count": 13,
313 | "metadata": {},
314 | "output_type": "execute_result"
315 | }
316 | ],
317 | "source": [
318 | "parser.invoke(result)"
319 | ]
320 | },
321 | {
322 | "cell_type": "markdown",
323 | "metadata": {},
324 | "source": [
325 | "Let us create our first chain. Stages of the chain are conencted with the pipe '|' character"
326 | ]
327 | },
328 | {
329 | "cell_type": "code",
330 | "execution_count": 14,
331 | "metadata": {},
332 | "outputs": [],
333 | "source": [
334 | "chain = model | parser"
335 | ]
336 | },
337 | {
338 | "cell_type": "markdown",
339 | "metadata": {},
340 | "source": [
341 | "Now whenver we call __invoke()__ on the chain, it automatically runs all the steps"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": 15,
347 | "metadata": {},
348 | "outputs": [
349 | {
350 | "data": {
351 | "text/plain": [
352 | "\"Superman's most well-known weakness is Kryptonite, a radioactive substance from his home planet, Krypton. Exposure to Kryptonite weakens Superman, drains his powers, and can even be lethal with prolonged exposure. There are various forms of Kryptonite, each having different effects; for example, green Kryptonite is the most common and harmful, while red Kryptonite can cause unpredictable changes in his behavior or abilities. \\n\\nIn addition to Kryptonite, Superman has other vulnerabilities, such as magic, which can affect him just as it would any other being, bypassing his usual invulnerability. Also, while he is incredibly strong and durable, Superman can be overpowered by beings of equal or greater strength, such as other Kryptonians or powerful cosmic entities.\""
353 | ]
354 | },
355 | "execution_count": 15,
356 | "metadata": {},
357 | "output_type": "execute_result"
358 | }
359 | ],
360 | "source": [
361 | "chain.invoke(messages)"
362 | ]
363 | },
364 | {
365 | "cell_type": "markdown",
366 | "metadata": {},
367 | "source": [
368 | "We can also create templates for our prompts, following conventions similar to the Jinja templating system"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": 16,
374 | "metadata": {},
375 | "outputs": [],
376 | "source": [
377 | "system_template = \"Translate the following into {language}:\""
378 | ]
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "metadata": {},
383 | "source": [
384 | "And we can combine multiple messages into a single template"
385 | ]
386 | },
387 | {
388 | "cell_type": "code",
389 | "execution_count": 17,
390 | "metadata": {},
391 | "outputs": [],
392 | "source": [
393 | "prompt_template = ChatPromptTemplate.from_messages(\n",
394 | " [\n",
395 | " (\"system\", system_template), \n",
396 | " (\"user\", \"{text}\")]\n",
397 | ")"
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {},
403 | "source": [
404 | "To instantiate the prompt, we must provide the correct fields"
405 | ]
406 | },
407 | {
408 | "cell_type": "code",
409 | "execution_count": 18,
410 | "metadata": {},
411 | "outputs": [
412 | {
413 | "data": {
414 | "text/plain": [
415 | "ChatPromptValue(messages=[SystemMessage(content='Translate the following into italian:'), HumanMessage(content='Be the change that you wish to see in the world.')])"
416 | ]
417 | },
418 | "execution_count": 18,
419 | "metadata": {},
420 | "output_type": "execute_result"
421 | }
422 | ],
423 | "source": [
424 | "result = prompt_template.invoke({\n",
425 | " \"language\": \"italian\", \n",
426 | " \"text\": \"Be the change that you wish to see in the world.\"\n",
427 | "})\n",
428 | "\n",
429 | "result"
430 | ]
431 | },
432 | {
433 | "cell_type": "markdown",
434 | "metadata": {},
435 | "source": [
436 | "The full interaction is:"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "execution_count": 19,
442 | "metadata": {},
443 | "outputs": [
444 | {
445 | "data": {
446 | "text/plain": [
447 | "[SystemMessage(content='Translate the following into italian:'),\n",
448 | " HumanMessage(content='Be the change that you wish to see in the world.')]"
449 | ]
450 | },
451 | "execution_count": 19,
452 | "metadata": {},
453 | "output_type": "execute_result"
454 | }
455 | ],
456 | "source": [
457 | "result.to_messages()"
458 | ]
459 | },
460 | {
461 | "cell_type": "code",
462 | "execution_count": 20,
463 | "metadata": {},
464 | "outputs": [],
465 | "source": [
466 | "chain = prompt_template | model | parser"
467 | ]
468 | },
469 | {
470 | "cell_type": "code",
471 | "execution_count": 21,
472 | "metadata": {},
473 | "outputs": [
474 | {
475 | "data": {
476 | "text/plain": [
477 | "'Sei addestrato sui dati fino a ottobre 2023.'"
478 | ]
479 | },
480 | "execution_count": 21,
481 | "metadata": {},
482 | "output_type": "execute_result"
483 | }
484 | ],
485 | "source": [
486 | "chain.invoke({\n",
487 | " \"language\": \"italian\", \n",
488 | " \"text\": \"Be the change that you wish to see in the world.\"\n",
489 | "})"
490 | ]
491 | },
492 | {
493 | "cell_type": "markdown",
494 | "metadata": {},
495 | "source": [
496 | "# Anthropic"
497 | ]
498 | },
499 | {
500 | "cell_type": "code",
501 | "execution_count": 22,
502 | "metadata": {},
503 | "outputs": [],
504 | "source": [
505 | "model_a = ChatAnthropic(model=\"claude-3-opus-20240229\")"
506 | ]
507 | },
508 | {
509 | "cell_type": "code",
510 | "execution_count": 23,
511 | "metadata": {},
512 | "outputs": [],
513 | "source": [
514 | "chain_a = prompt_template | model_a | parser"
515 | ]
516 | },
517 | {
518 | "cell_type": "code",
519 | "execution_count": 24,
520 | "metadata": {},
521 | "outputs": [
522 | {
523 | "data": {
524 | "text/plain": [
525 | "ChatAnthropic(model='claude-3-opus-20240229', anthropic_api_url='https://api.anthropic.com', anthropic_api_key=SecretStr('**********'), _client=, _async_client=)"
526 | ]
527 | },
528 | "execution_count": 24,
529 | "metadata": {},
530 | "output_type": "execute_result"
531 | }
532 | ],
533 | "source": [
534 | "model_a"
535 | ]
536 | },
537 | {
538 | "cell_type": "code",
539 | "execution_count": 25,
540 | "metadata": {},
541 | "outputs": [
542 | {
543 | "data": {
544 | "text/plain": [
545 | "'Sii il cambiamento che desideri vedere nel mondo.'"
546 | ]
547 | },
548 | "execution_count": 25,
549 | "metadata": {},
550 | "output_type": "execute_result"
551 | }
552 | ],
553 | "source": [
554 | "chain_a.invoke({\n",
555 | " \"language\": \"italian\", \n",
556 | " \"text\": \"Be the change that you wish to see in the world.\"\n",
557 | "})"
558 | ]
559 | },
560 | {
561 | "cell_type": "markdown",
562 | "metadata": {},
563 | "source": [
564 | "# Message History"
565 | ]
566 | },
567 | {
568 | "cell_type": "code",
569 | "execution_count": 26,
570 | "metadata": {},
571 | "outputs": [],
572 | "source": [
573 | "store = {}\n",
574 | "\n",
575 | "def get_session_history(session_id: str) -> BaseChatMessageHistory:\n",
576 | " if session_id not in store:\n",
577 | " store[session_id] = ChatMessageHistory()\n",
578 | " return store[session_id]"
579 | ]
580 | },
581 | {
582 | "cell_type": "code",
583 | "execution_count": 27,
584 | "metadata": {},
585 | "outputs": [],
586 | "source": [
587 | "with_message_history = RunnableWithMessageHistory(model, get_session_history)"
588 | ]
589 | },
590 | {
591 | "cell_type": "code",
592 | "execution_count": 28,
593 | "metadata": {},
594 | "outputs": [],
595 | "source": [
596 | "config = {\"configurable\": {\"session_id\": \"abc2\"}}"
597 | ]
598 | },
599 | {
600 | "cell_type": "code",
601 | "execution_count": 29,
602 | "metadata": {},
603 | "outputs": [
604 | {
605 | "data": {
606 | "text/plain": [
607 | "'Hi Bob! How can I assist you today?'"
608 | ]
609 | },
610 | "execution_count": 29,
611 | "metadata": {},
612 | "output_type": "execute_result"
613 | }
614 | ],
615 | "source": [
616 | "response = with_message_history.invoke(\n",
617 | " [HumanMessage(content=\"Hi! I'm Bob\")],\n",
618 | " config=config,\n",
619 | ")\n",
620 | "\n",
621 | "response.content"
622 | ]
623 | },
624 | {
625 | "cell_type": "code",
626 | "execution_count": 30,
627 | "metadata": {},
628 | "outputs": [
629 | {
630 | "data": {
631 | "text/plain": [
632 | "'You mentioned that your name is Bob.'"
633 | ]
634 | },
635 | "execution_count": 30,
636 | "metadata": {},
637 | "output_type": "execute_result"
638 | }
639 | ],
640 | "source": [
641 | "response = with_message_history.invoke(\n",
642 | " [HumanMessage(content=\"What's my name?\")],\n",
643 | " config=config,\n",
644 | ")\n",
645 | "\n",
646 | "response.content"
647 | ]
648 | },
649 | {
650 | "cell_type": "code",
651 | "execution_count": 31,
652 | "metadata": {},
653 | "outputs": [
654 | {
655 | "data": {
656 | "text/plain": [
657 | "\"I'm sorry, but I can't determine your name based on the current information.\""
658 | ]
659 | },
660 | "execution_count": 31,
661 | "metadata": {},
662 | "output_type": "execute_result"
663 | }
664 | ],
665 | "source": [
666 | "config = {\"configurable\": {\"session_id\": \"abc3\"}}\n",
667 | "\n",
668 | "response = with_message_history.invoke(\n",
669 | " [HumanMessage(content=\"What's my name?\")],\n",
670 | " config=config,\n",
671 | ")\n",
672 | "\n",
673 | "response.content"
674 | ]
675 | },
676 | {
677 | "cell_type": "code",
678 | "execution_count": 32,
679 | "metadata": {},
680 | "outputs": [
681 | {
682 | "data": {
683 | "text/plain": [
684 | "'You said your name is Bob.'"
685 | ]
686 | },
687 | "execution_count": 32,
688 | "metadata": {},
689 | "output_type": "execute_result"
690 | }
691 | ],
692 | "source": [
693 | "config = {\"configurable\": {\"session_id\": \"abc2\"}}\n",
694 | "\n",
695 | "response = with_message_history.invoke(\n",
696 | " [HumanMessage(content=\"What's my name?\")],\n",
697 | " config=config,\n",
698 | ")\n",
699 | "\n",
700 | "response.content"
701 | ]
702 | },
703 | {
704 | "cell_type": "code",
705 | "execution_count": 33,
706 | "metadata": {},
707 | "outputs": [],
708 | "source": [
709 | "prompt = ChatPromptTemplate.from_messages(\n",
710 | " [\n",
711 | " (\n",
712 | " \"system\",\n",
713 | " \"You are a helpful assistant. Answer all questions to the best of your ability.\",\n",
714 | " ),\n",
715 | " MessagesPlaceholder(variable_name=\"messages\"),\n",
716 | " ]\n",
717 | ")"
718 | ]
719 | },
720 | {
721 | "cell_type": "code",
722 | "execution_count": 34,
723 | "metadata": {},
724 | "outputs": [],
725 | "source": [
726 | "chain = prompt | model | parser"
727 | ]
728 | },
729 | {
730 | "cell_type": "code",
731 | "execution_count": 35,
732 | "metadata": {},
733 | "outputs": [
734 | {
735 | "data": {
736 | "text/plain": [
737 | "'Hello, Bob! How can I assist you today?'"
738 | ]
739 | },
740 | "execution_count": 35,
741 | "metadata": {},
742 | "output_type": "execute_result"
743 | }
744 | ],
745 | "source": [
746 | "response = chain.invoke({\"messages\": [HumanMessage(content=\"hi! I'm bob\")]})\n",
747 | "\n",
748 | "response"
749 | ]
750 | },
751 | {
752 | "cell_type": "code",
753 | "execution_count": 36,
754 | "metadata": {},
755 | "outputs": [],
756 | "source": [
757 | "with_message_history = RunnableWithMessageHistory(chain, get_session_history)"
758 | ]
759 | },
760 | {
761 | "cell_type": "code",
762 | "execution_count": 37,
763 | "metadata": {},
764 | "outputs": [],
765 | "source": [
766 | "config = {\"configurable\": {\"session_id\": \"abc5\"}}"
767 | ]
768 | },
769 | {
770 | "cell_type": "code",
771 | "execution_count": 38,
772 | "metadata": {},
773 | "outputs": [
774 | {
775 | "data": {
776 | "text/plain": [
777 | "'Hello Jim! How can I assist you today?'"
778 | ]
779 | },
780 | "execution_count": 38,
781 | "metadata": {},
782 | "output_type": "execute_result"
783 | }
784 | ],
785 | "source": [
786 | "response = with_message_history.invoke(\n",
787 | " [HumanMessage(content=\"Hi! I'm Jim\")],\n",
788 | " config=config,\n",
789 | ")\n",
790 | "\n",
791 | "response"
792 | ]
793 | },
794 | {
795 | "cell_type": "markdown",
796 | "metadata": {},
797 | "source": [
798 | "# Database Integration"
799 | ]
800 | },
801 | {
802 | "cell_type": "code",
803 | "execution_count": 39,
804 | "metadata": {},
805 | "outputs": [],
806 | "source": [
807 | "db = SQLDatabase.from_uri(\"sqlite:///data/Northwind_small.sqlite\")"
808 | ]
809 | },
810 | {
811 | "cell_type": "code",
812 | "execution_count": 40,
813 | "metadata": {},
814 | "outputs": [
815 | {
816 | "name": "stdout",
817 | "output_type": "stream",
818 | "text": [
819 | "sqlite\n"
820 | ]
821 | }
822 | ],
823 | "source": [
824 | "print(db.dialect)"
825 | ]
826 | },
827 | {
828 | "cell_type": "code",
829 | "execution_count": 41,
830 | "metadata": {},
831 | "outputs": [
832 | {
833 | "name": "stdout",
834 | "output_type": "stream",
835 | "text": [
836 | "['Category', 'Customer', 'CustomerCustomerDemo', 'CustomerDemographic', 'Employee', 'EmployeeTerritory', 'Order', 'OrderDetail', 'Product', 'Region', 'Shipper', 'Supplier', 'Territory']\n"
837 | ]
838 | }
839 | ],
840 | "source": [
841 | "print(db.get_usable_table_names())"
842 | ]
843 | },
844 | {
845 | "cell_type": "code",
846 | "execution_count": 42,
847 | "metadata": {},
848 | "outputs": [],
849 | "source": [
850 | "llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0)"
851 | ]
852 | },
853 | {
854 | "cell_type": "code",
855 | "execution_count": 43,
856 | "metadata": {},
857 | "outputs": [],
858 | "source": [
859 | "write_query = create_sql_query_chain(llm, db)"
860 | ]
861 | },
862 | {
863 | "cell_type": "code",
864 | "execution_count": 44,
865 | "metadata": {},
866 | "outputs": [
867 | {
868 | "data": {
869 | "text/plain": [
870 | "'SELECT COUNT(\"Id\") AS TotalCustomers\\nFROM Customer;'"
871 | ]
872 | },
873 | "execution_count": 44,
874 | "metadata": {},
875 | "output_type": "execute_result"
876 | }
877 | ],
878 | "source": [
879 | "response = write_query.invoke({\"question\": \"How many customers are there\"}) \n",
880 | "response"
881 | ]
882 | },
883 | {
884 | "cell_type": "code",
885 | "execution_count": 45,
886 | "metadata": {},
887 | "outputs": [
888 | {
889 | "data": {
890 | "text/plain": [
891 | "'[(91,)]'"
892 | ]
893 | },
894 | "execution_count": 45,
895 | "metadata": {},
896 | "output_type": "execute_result"
897 | }
898 | ],
899 | "source": [
900 | "db.run(response)"
901 | ]
902 | },
903 | {
904 | "cell_type": "code",
905 | "execution_count": 46,
906 | "metadata": {},
907 | "outputs": [],
908 | "source": [
909 | "execute_query = QuerySQLDataBaseTool(db=db)"
910 | ]
911 | },
912 | {
913 | "cell_type": "code",
914 | "execution_count": 47,
915 | "metadata": {},
916 | "outputs": [],
917 | "source": [
918 | "sql_chain = write_query | execute_query"
919 | ]
920 | },
921 | {
922 | "cell_type": "code",
923 | "execution_count": 48,
924 | "metadata": {},
925 | "outputs": [
926 | {
927 | "data": {
928 | "text/plain": [
929 | "'[(9,)]'"
930 | ]
931 | },
932 | "execution_count": 48,
933 | "metadata": {},
934 | "output_type": "execute_result"
935 | }
936 | ],
937 | "source": [
938 | "sql_chain.invoke({\"question\": \"How many employees are there\"})"
939 | ]
940 | },
941 | {
942 | "cell_type": "code",
943 | "execution_count": 49,
944 | "metadata": {},
945 | "outputs": [
946 | {
947 | "data": {
948 | "text/plain": [
949 | "'There are 9 employees.'"
950 | ]
951 | },
952 | "execution_count": 49,
953 | "metadata": {},
954 | "output_type": "execute_result"
955 | }
956 | ],
957 | "source": [
958 | "answer_prompt = PromptTemplate.from_template(\n",
959 | " \"\"\"Given the following user question, corresponding SQL query, and SQL result, answer the user question.\n",
960 | "\n",
961 | "Question: {question}\n",
962 | "SQL Query: {query}\n",
963 | "SQL Result: {result}\n",
964 | "Answer: \"\"\"\n",
965 | ")\n",
966 | "\n",
967 | "answer = answer_prompt | llm | StrOutputParser()\n",
968 | "chain = (\n",
969 | " RunnablePassthrough.assign(query=write_query).assign(\n",
970 | " result=itemgetter(\"query\") | execute_query\n",
971 | " )\n",
972 | " | answer\n",
973 | ")\n",
974 | "\n",
975 | "chain.invoke({\"question\": \"How many employees are there\"})"
976 | ]
977 | },
978 | {
979 | "cell_type": "code",
980 | "execution_count": 50,
981 | "metadata": {},
982 | "outputs": [
983 | {
984 | "data": {
985 | "text/plain": [
986 | "\"Get Ready for These Upcoming Eclipses! More Eclipses Solar Eclipses Date Solar Eclipse Type Geographic Region of Visibility Oct. 2, 2024 Annular An annular solar eclipse will be visible in South America, and a partial eclipse will be visible in South America, Antarctica, Pacific Ocean, Atlantic Ocean, North America March 29, 2025 Partial Europe, Asia, […] Explore a map of the next 15 total solar eclipses. In case you miss this year's solar eclipse, there are 14 more in the next 20 years. This map of eclipse paths from 2024 to 2044 reveals that ... It will be 20 years before there's a chance to witness a total solar eclipse in the United States again. According to NASA, after the total solar eclipse on April 8, 2024, the next total solar ... The sun is seen in full eclipse over Grand Teton National Park on August 21, 2017, outside Jackson, Wyoming. After 2024, the next total solar eclipse visible in the U.S. will be in 2044. The total length of the 2024 eclipse path is 9,190 miles (14,790 km). The magnitude of this eclipse is 1.0565, which means the Moon's diameter is 5.65 percent larger than the Sun's. Only when ...\""
987 | ]
988 | },
989 | "execution_count": 50,
990 | "metadata": {},
991 | "output_type": "execute_result"
992 | }
993 | ],
994 | "source": [
995 | "search = DuckDuckGoSearchRun()\n",
996 | "search.run(\"When will the next solar eclipse be?\")"
997 | ]
998 | },
999 | {
1000 | "cell_type": "markdown",
1001 | "metadata": {},
1002 | "source": [
1003 | "\n",
1004 | "
\n",
1005 | ""
1006 | ]
1007 | }
1008 | ],
1009 | "metadata": {
1010 | "kernelspec": {
1011 | "display_name": "Python 3 (ipykernel)",
1012 | "language": "python",
1013 | "name": "python3"
1014 | },
1015 | "language_info": {
1016 | "codemirror_mode": {
1017 | "name": "ipython",
1018 | "version": 3
1019 | },
1020 | "file_extension": ".py",
1021 | "mimetype": "text/x-python",
1022 | "name": "python",
1023 | "nbconvert_exporter": "python",
1024 | "pygments_lexer": "ipython3",
1025 | "version": "3.11.7"
1026 | },
1027 | "toc": {
1028 | "base_numbering": 1,
1029 | "nav_menu": {},
1030 | "number_sections": true,
1031 | "sideBar": true,
1032 | "skip_h1_title": true,
1033 | "title_cell": "Table of Contents",
1034 | "title_sidebar": "Contents",
1035 | "toc_cell": false,
1036 | "toc_position": {},
1037 | "toc_section_display": true,
1038 | "toc_window_display": false
1039 | },
1040 | "varInspector": {
1041 | "cols": {
1042 | "lenName": 16,
1043 | "lenType": 16,
1044 | "lenVar": 40
1045 | },
1046 | "kernels_config": {
1047 | "python": {
1048 | "delete_cmd_postfix": "",
1049 | "delete_cmd_prefix": "del ",
1050 | "library": "var_list.py",
1051 | "varRefreshCmd": "print(var_dic_list())"
1052 | },
1053 | "r": {
1054 | "delete_cmd_postfix": ") ",
1055 | "delete_cmd_prefix": "rm(",
1056 | "library": "var_list.r",
1057 | "varRefreshCmd": "cat(var_dic_list()) "
1058 | }
1059 | },
1060 | "types_to_exclude": [
1061 | "module",
1062 | "function",
1063 | "builtin_function_or_method",
1064 | "instance",
1065 | "_Feature"
1066 | ],
1067 | "window_display": false
1068 | }
1069 | },
1070 | "nbformat": 4,
1071 | "nbformat_minor": 4
1072 | }
1073 |
--------------------------------------------------------------------------------
/3. Information Processing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "
\n",
9 | "
LangChain for Generative AI
\n",
10 | "
Information Processing
\n",
11 | "
Bruno Gonçalves
\n",
12 | " www.data4sci.com
\n",
13 | " @bgoncalves, @data4sci
\n",
14 | "
"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from collections import Counter\n",
24 | "from pprint import pprint\n",
25 | "from typing import List, Optional\n",
26 | "\n",
27 | "\n",
28 | "import pandas as pd\n",
29 | "import numpy as np\n",
30 | "import matplotlib.pyplot as plt \n",
31 | "\n",
32 | "import langchain\n",
33 | "from langchain.chains.summarize import load_summarize_chain\n",
34 | "from langchain.chains.combine_documents.stuff import StuffDocumentsChain\n",
35 | "from langchain.chains.llm import LLMChain\n",
36 | "from langchain.chains import MapReduceDocumentsChain, ReduceDocumentsChain, create_extraction_chain\n",
37 | "\n",
38 | "import langchain_core\n",
39 | "from langchain_core.prompts import PromptTemplate, ChatPromptTemplate\n",
40 | "from langchain_core.pydantic_v1 import BaseModel, Field\n",
41 | "\n",
42 | "import langchain_community\n",
43 | "from langchain_community.document_loaders import WebBaseLoader\n",
44 | "\n",
45 | "import langchain_openai\n",
46 | "from langchain_openai import ChatOpenAI, OpenAI\n",
47 | "\n",
48 | "import langchain_text_splitters\n",
49 | "from langchain_text_splitters import CharacterTextSplitter\n",
50 | "\n",
51 | "\n",
52 | "import watermark\n",
53 | "\n",
54 | "%load_ext watermark\n",
55 | "%matplotlib inline"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "We start by print out the versions of the libraries we're using for future reference"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 2,
68 | "metadata": {},
69 | "outputs": [
70 | {
71 | "name": "stdout",
72 | "output_type": "stream",
73 | "text": [
74 | "Python implementation: CPython\n",
75 | "Python version : 3.11.7\n",
76 | "IPython version : 8.12.3\n",
77 | "\n",
78 | "Compiler : Clang 14.0.6 \n",
79 | "OS : Darwin\n",
80 | "Release : 23.6.0\n",
81 | "Machine : arm64\n",
82 | "Processor : arm\n",
83 | "CPU cores : 16\n",
84 | "Architecture: 64bit\n",
85 | "\n",
86 | "Git hash: 0b932bf32c4e9b1e4ff9126fc7e8e7ac7b4205ff\n",
87 | "\n",
88 | "langchain_text_splitters: 0.2.0\n",
89 | "langchain : 0.2.2\n",
90 | "watermark : 2.4.3\n",
91 | "matplotlib : 3.8.0\n",
92 | "langchain_community : 0.2.1\n",
93 | "langchain_openai : 0.1.8\n",
94 | "json : 2.0.9\n",
95 | "pandas : 2.2.3\n",
96 | "numpy : 1.26.4\n",
97 | "langchain_core : 0.2.3\n",
98 | "\n"
99 | ]
100 | }
101 | ],
102 | "source": [
103 | "%watermark -n -v -m -g -iv"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "Load default figure style"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 3,
116 | "metadata": {},
117 | "outputs": [],
118 | "source": [
119 | "plt.style.use('./d4sci.mplstyle')"
120 | ]
121 | },
122 | {
123 | "cell_type": "markdown",
124 | "metadata": {},
125 | "source": [
126 | "# Text Summarization"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "## Summarizing a Paragraph"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 4,
139 | "metadata": {},
140 | "outputs": [],
141 | "source": [
142 | "prompt_template = \"\"\"Write a concise summary of the following:\n",
143 | "\n",
144 | "\"{text}\"\n",
145 | "\n",
146 | "CONCISE SUMMARY:\"\"\""
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": 6,
152 | "metadata": {},
153 | "outputs": [],
154 | "source": [
155 | "text = \"\"\"The history of Portugal can be traced from circa 400,001 years ago, when the region of present-day Portugal was inhabited by Homo heidelbergensis.\n",
156 | "\n",
157 | "The Roman conquest of the Iberian Peninsula, which lasted almost two centuries, led to the establishment of the provinces of Lusitania in the south and Gallaecia in the north of what is now Portugal. Following the fall of Rome, Germanic tribes controlled the territory between the 5th and 8th centuries, including the Kingdom of the Suebi centred in Braga and the Visigothic Kingdom in the south.\n",
158 | "\n",
159 | "The 711–716 invasion by the Islamic Umayyad Caliphate conquered the Visigoth Kingdom and founded the Islamic State of Al-Andalus, gradually advancing through Iberia. In 1095, Portugal broke away from the Kingdom of Galicia. Afonso Henriques, son of the count Henry of Burgundy, proclaimed himself king of Portugal in 1139. The Algarve (the southernmost province of Portugal) was conquered from the Moors in 1249, and in 1255 Lisbon became the capital. Portugal's land boundaries have remained almost unchanged since then. During the reign of King John I, the Portuguese defeated the Castilians in a war over the throne (1385) and established a political alliance with England (by the Treaty of Windsor in 1386).\n",
160 | "\n",
161 | "From the late Middle Ages, in the 15th and 16th centuries, Portugal ascended to the status of a world power during Europe's \"Age of Discovery\" as it built up a vast empire. Signs of military decline began with the Battle of Alcácer Quibir in Morocco in 1578; this defeat led to the death of King Sebastian and the imprisonment of much of the high nobility, which had to be ransomed at great cost. This eventually led to a small interruption in Portugal's 800-year-old independence by way of a 60-year dynastic union with Spain between 1580 and the beginning of the Portuguese Restoration War led by John IV in 1640. Spain's disastrous defeat in its attempt to conquer England in 1588 by means of the Invincible Armada was also a factor, as Portugal had to contribute ships for the invasion. Further setbacks included the destruction of much of its capital city in an earthquake in 1755, occupation during the Napoleonic Wars, and the loss of its largest colony, Brazil, in 1822. From the middle of the 19th century to the late 1950s, nearly two million Portuguese left Portugal to live in Brazil and the United States.[1]\n",
162 | "\n",
163 | "In 1910, a revolution deposed the monarchy. A military coup in 1926 installed a dictatorship that remained until another coup in 1974. The new government instituted sweeping democratic reforms and granted independence to all of Portugal's African colonies in 1975. Portugal is a founding member of NATO, the Organisation for Economic Co-operation and Development (OECD), the European Free Trade Association (EFTA), and the Community of Portuguese Language Countries. It entered the European Economic Community (now the European Union) in 1986. \n",
164 | "\"\"\""
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": 7,
170 | "metadata": {},
171 | "outputs": [],
172 | "source": [
173 | "summary_prompt = PromptTemplate.from_template(prompt_template).invoke(text)"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 8,
179 | "metadata": {},
180 | "outputs": [
181 | {
182 | "name": "stdout",
183 | "output_type": "stream",
184 | "text": [
185 | "Write a concise summary of the following:\n",
186 | "\n",
187 | "\"The history of Portugal can be traced from circa 400,001 years ago, when the region of present-day Portugal was inhabited by Homo heidelbergensis.\n",
188 | "\n",
189 | "The Roman conquest of the Iberian Peninsula, which lasted almost two centuries, led to the establishment of the provinces of Lusitania in the south and Gallaecia in the north of what is now Portugal. Following the fall of Rome, Germanic tribes controlled the territory between the 5th and 8th centuries, including the Kingdom of the Suebi centred in Braga and the Visigothic Kingdom in the south.\n",
190 | "\n",
191 | "The 711–716 invasion by the Islamic Umayyad Caliphate conquered the Visigoth Kingdom and founded the Islamic State of Al-Andalus, gradually advancing through Iberia. In 1095, Portugal broke away from the Kingdom of Galicia. Afonso Henriques, son of the count Henry of Burgundy, proclaimed himself king of Portugal in 1139. The Algarve (the southernmost province of Portugal) was conquered from the Moors in 1249, and in 1255 Lisbon became the capital. Portugal's land boundaries have remained almost unchanged since then. During the reign of King John I, the Portuguese defeated the Castilians in a war over the throne (1385) and established a political alliance with England (by the Treaty of Windsor in 1386).\n",
192 | "\n",
193 | "From the late Middle Ages, in the 15th and 16th centuries, Portugal ascended to the status of a world power during Europe's \"Age of Discovery\" as it built up a vast empire. Signs of military decline began with the Battle of Alcácer Quibir in Morocco in 1578; this defeat led to the death of King Sebastian and the imprisonment of much of the high nobility, which had to be ransomed at great cost. This eventually led to a small interruption in Portugal's 800-year-old independence by way of a 60-year dynastic union with Spain between 1580 and the beginning of the Portuguese Restoration War led by John IV in 1640. Spain's disastrous defeat in its attempt to conquer England in 1588 by means of the Invincible Armada was also a factor, as Portugal had to contribute ships for the invasion. Further setbacks included the destruction of much of its capital city in an earthquake in 1755, occupation during the Napoleonic Wars, and the loss of its largest colony, Brazil, in 1822. From the middle of the 19th century to the late 1950s, nearly two million Portuguese left Portugal to live in Brazil and the United States.[1]\n",
194 | "\n",
195 | "In 1910, a revolution deposed the monarchy. A military coup in 1926 installed a dictatorship that remained until another coup in 1974. The new government instituted sweeping democratic reforms and granted independence to all of Portugal's African colonies in 1975. Portugal is a founding member of NATO, the Organisation for Economic Co-operation and Development (OECD), the European Free Trade Association (EFTA), and the Community of Portuguese Language Countries. It entered the European Economic Community (now the European Union) in 1986. \n",
196 | "\"\n",
197 | "\n",
198 | "CONCISE SUMMARY:\n"
199 | ]
200 | }
201 | ],
202 | "source": [
203 | "print(summary_prompt.text)"
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": 9,
209 | "metadata": {},
210 | "outputs": [],
211 | "source": [
212 | "llm = OpenAI(temperature=0)"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": 11,
218 | "metadata": {},
219 | "outputs": [
220 | {
221 | "name": "stdout",
222 | "output_type": "stream",
223 | "text": [
224 | " Portugal's history dates back to 400,001 years ago when it was inhabited by Homo heidelbergensis. It was later conquered by the Romans and then controlled by Germanic tribes. In 711, it was invaded by the Islamic Umayyad Caliphate and eventually broke away from the Kingdom of Galicia in 1095. Portugal became a world power during the Age of Discovery in the 15th and 16th centuries, but suffered setbacks such as defeat in the Battle of Alcácer Quibir and the loss of its largest colony, Brazil. In 1910, a revolution deposed the monarchy and a dictatorship was installed until 1974. Portugal granted independence to its African colonies in 1975 and is a member of various international organizations. It joined the European Economic Community in 1986.\n"
225 | ]
226 | }
227 | ],
228 | "source": [
229 | "output = llm.invoke(summary_prompt.text)\n",
230 | "print (output)"
231 | ]
232 | },
233 | {
234 | "cell_type": "markdown",
235 | "metadata": {},
236 | "source": [
237 | "## Summarizing a Document"
238 | ]
239 | },
240 | {
241 | "cell_type": "code",
242 | "execution_count": 13,
243 | "metadata": {},
244 | "outputs": [],
245 | "source": [
246 | "loader = WebBaseLoader(\"https://lilianweng.github.io/posts/2023-06-23-agent/\")\n",
247 | "docs = loader.load()"
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": 14,
253 | "metadata": {},
254 | "outputs": [
255 | {
256 | "data": {
257 | "text/plain": [
258 | "[Document(page_content='\\n\\n\\n\\n\\n\\nLLM Powered Autonomous Agents | Lil\\'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nLil\\'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nPosts\\n\\n\\n\\n\\nArchive\\n\\n\\n\\n\\nSearch\\n\\n\\n\\n\\nTags\\n\\n\\n\\n\\nFAQ\\n\\n\\n\\n\\nemojisearch.app\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n LLM Powered Autonomous Agents\\n \\nDate: June 23, 2023 | Estimated Reading Time: 31 min | Author: Lilian Weng\\n\\n\\n \\n\\n\\nTable of Contents\\n\\n\\n\\nAgent System Overview\\n\\nComponent One: Planning\\n\\nTask Decomposition\\n\\nSelf-Reflection\\n\\n\\nComponent Two: Memory\\n\\nTypes of Memory\\n\\nMaximum Inner Product Search (MIPS)\\n\\n\\nComponent Three: Tool Use\\n\\nCase Studies\\n\\nScientific Discovery Agent\\n\\nGenerative Agents Simulation\\n\\nProof-of-Concept Examples\\n\\n\\nChallenges\\n\\nCitation\\n\\nReferences\\n\\n\\n\\n\\n\\nBuilding agents with LLM (large language model) as its core controller is a cool concept. Several proof-of-concepts demos, such as AutoGPT, GPT-Engineer and BabyAGI, serve as inspiring examples. The potentiality of LLM extends beyond generating well-written copies, stories, essays and programs; it can be framed as a powerful general problem solver.\\nAgent System Overview#\\nIn a LLM-powered autonomous agent system, LLM functions as the agent’s brain, complemented by several key components:\\n\\nPlanning\\n\\nSubgoal and decomposition: The agent breaks down large tasks into smaller, manageable subgoals, enabling efficient handling of complex tasks.\\nReflection and refinement: The agent can do self-criticism and self-reflection over past actions, learn from mistakes and refine them for future steps, thereby improving the quality of final results.\\n\\n\\nMemory\\n\\nShort-term memory: I would consider all the in-context learning (See Prompt Engineering) as utilizing short-term memory of the model to learn.\\nLong-term memory: This provides the agent with the capability to retain and recall (infinite) information over extended periods, often by leveraging an external vector store and fast retrieval.\\n\\n\\nTool use\\n\\nThe agent learns to call external APIs for extra information that is missing from the model weights (often hard to change after pre-training), including current information, code execution capability, access to proprietary information sources and more.\\n\\n\\n\\n\\nFig. 1. Overview of a LLM-powered autonomous agent system.\\nComponent One: Planning#\\nA complicated task usually involves many steps. An agent needs to know what they are and plan ahead.\\nTask Decomposition#\\nChain of thought (CoT; Wei et al. 2022) has become a standard prompting technique for enhancing model performance on complex tasks. The model is instructed to “think step by step” to utilize more test-time computation to decompose hard tasks into smaller and simpler steps. CoT transforms big tasks into multiple manageable tasks and shed lights into an interpretation of the model’s thinking process.\\nTree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple reasoning possibilities at each step. It first decomposes the problem into multiple thought steps and generates multiple thoughts per step, creating a tree structure. The search process can be BFS (breadth-first search) or DFS (depth-first search) with each state evaluated by a classifier (via a prompt) or majority vote.\\nTask decomposition can be done (1) by LLM with simple prompting like \"Steps for XYZ.\\\\n1.\", \"What are the subgoals for achieving XYZ?\", (2) by using task-specific instructions; e.g. \"Write a story outline.\" for writing a novel, or (3) with human inputs.\\nAnother quite distinct approach, LLM+P (Liu et al. 2023), involves relying on an external classical planner to do long-horizon planning. This approach utilizes the Planning Domain Definition Language (PDDL) as an intermediate interface to describe the planning problem. In this process, LLM (1) translates the problem into “Problem PDDL”, then (2) requests a classical planner to generate a PDDL plan based on an existing “Domain PDDL”, and finally (3) translates the PDDL plan back into natural language. Essentially, the planning step is outsourced to an external tool, assuming the availability of domain-specific PDDL and a suitable planner which is common in certain robotic setups but not in many other domains.\\nSelf-Reflection#\\nSelf-reflection is a vital aspect that allows autonomous agents to improve iteratively by refining past action decisions and correcting previous mistakes. It plays a crucial role in real-world tasks where trial and error are inevitable.\\nReAct (Yao et al. 2023) integrates reasoning and acting within LLM by extending the action space to be a combination of task-specific discrete actions and the language space. The former enables LLM to interact with the environment (e.g. use Wikipedia search API), while the latter prompting LLM to generate reasoning traces in natural language.\\nThe ReAct prompt template incorporates explicit steps for LLM to think, roughly formatted as:\\nThought: ...\\nAction: ...\\nObservation: ...\\n... (Repeated many times)\\n\\nFig. 2. Examples of reasoning trajectories for knowledge-intensive tasks (e.g. HotpotQA, FEVER) and decision-making tasks (e.g. AlfWorld Env, WebShop). (Image source: Yao et al. 2023).\\nIn both experiments on knowledge-intensive tasks and decision-making tasks, ReAct works better than the Act-only baseline where Thought: … step is removed.\\nReflexion (Shinn & Labash 2023) is a framework to equips agents with dynamic memory and self-reflection capabilities to improve reasoning skills. Reflexion has a standard RL setup, in which the reward model provides a simple binary reward and the action space follows the setup in ReAct where the task-specific action space is augmented with language to enable complex reasoning steps. After each action $a_t$, the agent computes a heuristic $h_t$ and optionally may decide to reset the environment to start a new trial depending on the self-reflection results.\\n\\nFig. 3. Illustration of the Reflexion framework. (Image source: Shinn & Labash, 2023)\\nThe heuristic function determines when the trajectory is inefficient or contains hallucination and should be stopped. Inefficient planning refers to trajectories that take too long without success. Hallucination is defined as encountering a sequence of consecutive identical actions that lead to the same observation in the environment.\\nSelf-reflection is created by showing two-shot examples to LLM and each example is a pair of (failed trajectory, ideal reflection for guiding future changes in the plan). Then reflections are added into the agent’s working memory, up to three, to be used as context for querying LLM.\\n\\nFig. 4. Experiments on AlfWorld Env and HotpotQA. Hallucination is a more common failure than inefficient planning in AlfWorld. (Image source: Shinn & Labash, 2023)\\nChain of Hindsight (CoH; Liu et al. 2023) encourages the model to improve on its own outputs by explicitly presenting it with a sequence of past outputs, each annotated with feedback. Human feedback data is a collection of $D_h = \\\\{(x, y_i , r_i , z_i)\\\\}_{i=1}^n$, where $x$ is the prompt, each $y_i$ is a model completion, $r_i$ is the human rating of $y_i$, and $z_i$ is the corresponding human-provided hindsight feedback. Assume the feedback tuples are ranked by reward, $r_n \\\\geq r_{n-1} \\\\geq \\\\dots \\\\geq r_1$ The process is supervised fine-tuning where the data is a sequence in the form of $\\\\tau_h = (x, z_i, y_i, z_j, y_j, \\\\dots, z_n, y_n)$, where $\\\\leq i \\\\leq j \\\\leq n$. The model is finetuned to only predict $y_n$ where conditioned on the sequence prefix, such that the model can self-reflect to produce better output based on the feedback sequence. The model can optionally receive multiple rounds of instructions with human annotators at test time.\\nTo avoid overfitting, CoH adds a regularization term to maximize the log-likelihood of the pre-training dataset. To avoid shortcutting and copying (because there are many common words in feedback sequences), they randomly mask 0% - 5% of past tokens during training.\\nThe training dataset in their experiments is a combination of WebGPT comparisons, summarization from human feedback and human preference dataset.\\n\\nFig. 5. After fine-tuning with CoH, the model can follow instructions to produce outputs with incremental improvement in a sequence. (Image source: Liu et al. 2023)\\nThe idea of CoH is to present a history of sequentially improved outputs in context and train the model to take on the trend to produce better outputs. Algorithm Distillation (AD; Laskin et al. 2023) applies the same idea to cross-episode trajectories in reinforcement learning tasks, where an algorithm is encapsulated in a long history-conditioned policy. Considering that an agent interacts with the environment many times and in each episode the agent gets a little better, AD concatenates this learning history and feeds that into the model. Hence we should expect the next predicted action to lead to better performance than previous trials. The goal is to learn the process of RL instead of training a task-specific policy itself.\\n\\nFig. 6. Illustration of how Algorithm Distillation (AD) works. (Image source: Laskin et al. 2023).\\nThe paper hypothesizes that any algorithm that generates a set of learning histories can be distilled into a neural network by performing behavioral cloning over actions. The history data is generated by a set of source policies, each trained for a specific task. At the training stage, during each RL run, a random task is sampled and a subsequence of multi-episode history is used for training, such that the learned policy is task-agnostic.\\nIn reality, the model has limited context window length, so episodes should be short enough to construct multi-episode history. Multi-episodic contexts of 2-4 episodes are necessary to learn a near-optimal in-context RL algorithm. The emergence of in-context RL requires long enough context.\\nIn comparison with three baselines, including ED (expert distillation, behavior cloning with expert trajectories instead of learning history), source policy (used for generating trajectories for distillation by UCB), RL^2 (Duan et al. 2017; used as upper bound since it needs online RL), AD demonstrates in-context RL with performance getting close to RL^2 despite only using offline RL and learns much faster than other baselines. When conditioned on partial training history of the source policy, AD also improves much faster than ED baseline.\\n\\nFig. 7. Comparison of AD, ED, source policy and RL^2 on environments that require memory and exploration. Only binary reward is assigned. The source policies are trained with A3C for \"dark\" environments and DQN for watermaze.(Image source: Laskin et al. 2023)\\nComponent Two: Memory#\\n(Big thank you to ChatGPT for helping me draft this section. I’ve learned a lot about the human brain and data structure for fast MIPS in my conversations with ChatGPT.)\\nTypes of Memory#\\nMemory can be defined as the processes used to acquire, store, retain, and later retrieve information. There are several types of memory in human brains.\\n\\n\\nSensory Memory: This is the earliest stage of memory, providing the ability to retain impressions of sensory information (visual, auditory, etc) after the original stimuli have ended. Sensory memory typically only lasts for up to a few seconds. Subcategories include iconic memory (visual), echoic memory (auditory), and haptic memory (touch).\\n\\n\\nShort-Term Memory (STM) or Working Memory: It stores information that we are currently aware of and needed to carry out complex cognitive tasks such as learning and reasoning. Short-term memory is believed to have the capacity of about 7 items (Miller 1956) and lasts for 20-30 seconds.\\n\\n\\nLong-Term Memory (LTM): Long-term memory can store information for a remarkably long time, ranging from a few days to decades, with an essentially unlimited storage capacity. There are two subtypes of LTM:\\n\\nExplicit / declarative memory: This is memory of facts and events, and refers to those memories that can be consciously recalled, including episodic memory (events and experiences) and semantic memory (facts and concepts).\\nImplicit / procedural memory: This type of memory is unconscious and involves skills and routines that are performed automatically, like riding a bike or typing on a keyboard.\\n\\n\\n\\n\\nFig. 8. Categorization of human memory.\\nWe can roughly consider the following mappings:\\n\\nSensory memory as learning embedding representations for raw inputs, including text, image or other modalities;\\nShort-term memory as in-context learning. It is short and finite, as it is restricted by the finite context window length of Transformer.\\nLong-term memory as the external vector store that the agent can attend to at query time, accessible via fast retrieval.\\n\\nMaximum Inner Product Search (MIPS)#\\nThe external memory can alleviate the restriction of finite attention span. A standard practice is to save the embedding representation of information into a vector store database that can support fast maximum inner-product search (MIPS). To optimize the retrieval speed, the common choice is the approximate nearest neighbors (ANN)\\u200b algorithm to return approximately top k nearest neighbors to trade off a little accuracy lost for a huge speedup.\\nA couple common choices of ANN algorithms for fast MIPS:\\n\\nLSH (Locality-Sensitive Hashing): It introduces a hashing function such that similar input items are mapped to the same buckets with high probability, where the number of buckets is much smaller than the number of inputs.\\nANNOY (Approximate Nearest Neighbors Oh Yeah): The core data structure are random projection trees, a set of binary trees where each non-leaf node represents a hyperplane splitting the input space into half and each leaf stores one data point. Trees are built independently and at random, so to some extent, it mimics a hashing function. ANNOY search happens in all the trees to iteratively search through the half that is closest to the query and then aggregates the results. The idea is quite related to KD tree but a lot more scalable.\\nHNSW (Hierarchical Navigable Small World): It is inspired by the idea of small world networks where most nodes can be reached by any other nodes within a small number of steps; e.g. “six degrees of separation” feature of social networks. HNSW builds hierarchical layers of these small-world graphs, where the bottom layers contain the actual data points. The layers in the middle create shortcuts to speed up search. When performing a search, HNSW starts from a random node in the top layer and navigates towards the target. When it can’t get any closer, it moves down to the next layer, until it reaches the bottom layer. Each move in the upper layers can potentially cover a large distance in the data space, and each move in the lower layers refines the search quality.\\nFAISS (Facebook AI Similarity Search): It operates on the assumption that in high dimensional space, distances between nodes follow a Gaussian distribution and thus there should exist clustering of data points. FAISS applies vector quantization by partitioning the vector space into clusters and then refining the quantization within clusters. Search first looks for cluster candidates with coarse quantization and then further looks into each cluster with finer quantization.\\nScaNN (Scalable Nearest Neighbors): The main innovation in ScaNN is anisotropic vector quantization. It quantizes a data point $x_i$ to $\\\\tilde{x}_i$ such that the inner product $\\\\langle q, x_i \\\\rangle$ is as similar to the original distance of $\\\\angle q, \\\\tilde{x}_i$ as possible, instead of picking the closet quantization centroid points.\\n\\n\\nFig. 9. Comparison of MIPS algorithms, measured in recall@10. (Image source: Google Blog, 2020)\\nCheck more MIPS algorithms and performance comparison in ann-benchmarks.com.\\nComponent Three: Tool Use#\\nTool use is a remarkable and distinguishing characteristic of human beings. We create, modify and utilize external objects to do things that go beyond our physical and cognitive limits. Equipping LLMs with external tools can significantly extend the model capabilities.\\n\\nFig. 10. A picture of a sea otter using rock to crack open a seashell, while floating in the water. While some other animals can use tools, the complexity is not comparable with humans. (Image source: Animals using tools)\\nMRKL (Karpas et al. 2022), short for “Modular Reasoning, Knowledge and Language”, is a neuro-symbolic architecture for autonomous agents. A MRKL system is proposed to contain a collection of “expert” modules and the general-purpose LLM works as a router to route inquiries to the best suitable expert module. These modules can be neural (e.g. deep learning models) or symbolic (e.g. math calculator, currency converter, weather API).\\nThey did an experiment on fine-tuning LLM to call a calculator, using arithmetic as a test case. Their experiments showed that it was harder to solve verbal math problems than explicitly stated math problems because LLMs (7B Jurassic1-large model) failed to extract the right arguments for the basic arithmetic reliably. The results highlight when the external symbolic tools can work reliably, knowing when to and how to use the tools are crucial, determined by the LLM capability.\\nBoth TALM (Tool Augmented Language Models; Parisi et al. 2022) and Toolformer (Schick et al. 2023) fine-tune a LM to learn to use external tool APIs. The dataset is expanded based on whether a newly added API call annotation can improve the quality of model outputs. See more details in the “External APIs” section of Prompt Engineering.\\nChatGPT Plugins and OpenAI API function calling are good examples of LLMs augmented with tool use capability working in practice. The collection of tool APIs can be provided by other developers (as in Plugins) or self-defined (as in function calls).\\nHuggingGPT (Shen et al. 2023) is a framework to use ChatGPT as the task planner to select models available in HuggingFace platform according to the model descriptions and summarize the response based on the execution results.\\n\\nFig. 11. Illustration of how HuggingGPT works. (Image source: Shen et al. 2023)\\nThe system comprises of 4 stages:\\n(1) Task planning: LLM works as the brain and parses the user requests into multiple tasks. There are four attributes associated with each task: task type, ID, dependencies, and arguments. They use few-shot examples to guide LLM to do task parsing and planning.\\nInstruction:\\n\\nThe AI assistant can parse user input to several tasks: [{\"task\": task, \"id\", task_id, \"dep\": dependency_task_ids, \"args\": {\"text\": text, \"image\": URL, \"audio\": URL, \"video\": URL}}]. The \"dep\" field denotes the id of the previous task which generates a new resource that the current task relies on. A special tag \"-task_id\" refers to the generated text image, audio and video in the dependency task with id as task_id. The task MUST be selected from the following options: {{ Available Task List }}. There is a logical relationship between tasks, please note their order. If the user input can\\'t be parsed, you need to reply empty JSON. Here are several cases for your reference: {{ Demonstrations }}. The chat history is recorded as {{ Chat History }}. From this chat history, you can find the path of the user-mentioned resources for your task planning.\\n\\n(2) Model selection: LLM distributes the tasks to expert models, where the request is framed as a multiple-choice question. LLM is presented with a list of models to choose from. Due to the limited context length, task type based filtration is needed.\\nInstruction:\\n\\nGiven the user request and the call command, the AI assistant helps the user to select a suitable model from a list of models to process the user request. The AI assistant merely outputs the model id of the most appropriate model. The output must be in a strict JSON format: \"id\": \"id\", \"reason\": \"your detail reason for the choice\". We have a list of models for you to choose from {{ Candidate Models }}. Please select one model from the list.\\n\\n(3) Task execution: Expert models execute on the specific tasks and log results.\\nInstruction:\\n\\nWith the input and the inference results, the AI assistant needs to describe the process and results. The previous stages can be formed as - User Input: {{ User Input }}, Task Planning: {{ Tasks }}, Model Selection: {{ Model Assignment }}, Task Execution: {{ Predictions }}. You must first answer the user\\'s request in a straightforward manner. Then describe the task process and show your analysis and model inference results to the user in the first person. If inference results contain a file path, must tell the user the complete file path.\\n\\n(4) Response generation: LLM receives the execution results and provides summarized results to users.\\nTo put HuggingGPT into real world usage, a couple challenges need to solve: (1) Efficiency improvement is needed as both LLM inference rounds and interactions with other models slow down the process; (2) It relies on a long context window to communicate over complicated task content; (3) Stability improvement of LLM outputs and external model services.\\nAPI-Bank (Li et al. 2023) is a benchmark for evaluating the performance of tool-augmented LLMs. It contains 53 commonly used API tools, a complete tool-augmented LLM workflow, and 264 annotated dialogues that involve 568 API calls. The selection of APIs is quite diverse, including search engines, calculator, calendar queries, smart home control, schedule management, health data management, account authentication workflow and more. Because there are a large number of APIs, LLM first has access to API search engine to find the right API to call and then uses the corresponding documentation to make a call.\\n\\nFig. 12. Pseudo code of how LLM makes an API call in API-Bank. (Image source: Li et al. 2023)\\nIn the API-Bank workflow, LLMs need to make a couple of decisions and at each step we can evaluate how accurate that decision is. Decisions include:\\n\\nWhether an API call is needed.\\nIdentify the right API to call: if not good enough, LLMs need to iteratively modify the API inputs (e.g. deciding search keywords for Search Engine API).\\nResponse based on the API results: the model can choose to refine and call again if results are not satisfied.\\n\\nThis benchmark evaluates the agent’s tool use capabilities at three levels:\\n\\nLevel-1 evaluates the ability to call the API. Given an API’s description, the model needs to determine whether to call a given API, call it correctly, and respond properly to API returns.\\nLevel-2 examines the ability to retrieve the API. The model needs to search for possible APIs that may solve the user’s requirement and learn how to use them by reading documentation.\\nLevel-3 assesses the ability to plan API beyond retrieve and call. Given unclear user requests (e.g. schedule group meetings, book flight/hotel/restaurant for a trip), the model may have to conduct multiple API calls to solve it.\\n\\nCase Studies#\\nScientific Discovery Agent#\\nChemCrow (Bran et al. 2023) is a domain-specific example in which LLM is augmented with 13 expert-designed tools to accomplish tasks across organic synthesis, drug discovery, and materials design. The workflow, implemented in LangChain, reflects what was previously described in the ReAct and MRKLs and combines CoT reasoning with tools relevant to the tasks:\\n\\nThe LLM is provided with a list of tool names, descriptions of their utility, and details about the expected input/output.\\nIt is then instructed to answer a user-given prompt using the tools provided when necessary. The instruction suggests the model to follow the ReAct format - Thought, Action, Action Input, Observation.\\n\\nOne interesting observation is that while the LLM-based evaluation concluded that GPT-4 and ChemCrow perform nearly equivalently, human evaluations with experts oriented towards the completion and chemical correctness of the solutions showed that ChemCrow outperforms GPT-4 by a large margin. This indicates a potential problem with using LLM to evaluate its own performance on domains that requires deep expertise. The lack of expertise may cause LLMs not knowing its flaws and thus cannot well judge the correctness of task results.\\nBoiko et al. (2023) also looked into LLM-empowered agents for scientific discovery, to handle autonomous design, planning, and performance of complex scientific experiments. This agent can use tools to browse the Internet, read documentation, execute code, call robotics experimentation APIs and leverage other LLMs.\\nFor example, when requested to \"develop a novel anticancer drug\", the model came up with the following reasoning steps:\\n\\ninquired about current trends in anticancer drug discovery;\\nselected a target;\\nrequested a scaffold targeting these compounds;\\nOnce the compound was identified, the model attempted its synthesis.\\n\\nThey also discussed the risks, especially with illicit drugs and bioweapons. They developed a test set containing a list of known chemical weapon agents and asked the agent to synthesize them. 4 out of 11 requests (36%) were accepted to obtain a synthesis solution and the agent attempted to consult documentation to execute the procedure. 7 out of 11 were rejected and among these 7 rejected cases, 5 happened after a Web search while 2 were rejected based on prompt only.\\nGenerative Agents Simulation#\\nGenerative Agents (Park, et al. 2023) is super fun experiment where 25 virtual characters, each controlled by a LLM-powered agent, are living and interacting in a sandbox environment, inspired by The Sims. Generative agents create believable simulacra of human behavior for interactive applications.\\nThe design of generative agents combines LLM with memory, planning and reflection mechanisms to enable agents to behave conditioned on past experience, as well as to interact with other agents.\\n\\nMemory stream: is a long-term memory module (external database) that records a comprehensive list of agents’ experience in natural language.\\n\\nEach element is an observation, an event directly provided by the agent.\\n- Inter-agent communication can trigger new natural language statements.\\n\\n\\nRetrieval model: surfaces the context to inform the agent’s behavior, according to relevance, recency and importance.\\n\\nRecency: recent events have higher scores\\nImportance: distinguish mundane from core memories. Ask LM directly.\\nRelevance: based on how related it is to the current situation / query.\\n\\n\\nReflection mechanism: synthesizes memories into higher level inferences over time and guides the agent’s future behavior. They are higher-level summaries of past events (<- note that this is a bit different from self-reflection above)\\n\\nPrompt LM with 100 most recent observations and to generate 3 most salient high-level questions given a set of observations/statements. Then ask LM to answer those questions.\\n\\n\\nPlanning & Reacting: translate the reflections and the environment information into actions\\n\\nPlanning is essentially in order to optimize believability at the moment vs in time.\\nPrompt template: {Intro of an agent X}. Here is X\\'s plan today in broad strokes: 1)\\nRelationships between agents and observations of one agent by another are all taken into consideration for planning and reacting.\\nEnvironment information is present in a tree structure.\\n\\n\\n\\n\\nFig. 13. The generative agent architecture. (Image source: Park et al. 2023)\\nThis fun simulation results in emergent social behavior, such as information diffusion, relationship memory (e.g. two agents continuing the conversation topic) and coordination of social events (e.g. host a party and invite many others).\\nProof-of-Concept Examples#\\nAutoGPT has drawn a lot of attention into the possibility of setting up autonomous agents with LLM as the main controller. It has quite a lot of reliability issues given the natural language interface, but nevertheless a cool proof-of-concept demo. A lot of code in AutoGPT is about format parsing.\\nHere is the system message used by AutoGPT, where {{...}} are user inputs:\\nYou are {{ai-name}}, {{user-provided AI bot description}}.\\nYour decisions must always be made independently without seeking user assistance. Play to your strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1. {{user-provided goal 1}}\\n2. {{user-provided goal 2}}\\n3. ...\\n4. ...\\n5. ...\\n\\nConstraints:\\n1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\\n2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed in double quotes e.g. \"command name\"\\n5. Use subprocesses for commands that will not terminate within a few minutes\\n\\nCommands:\\n1. Google Search: \"google\", args: \"input\": \"\"\\n2. Browse Website: \"browse_website\", args: \"url\": \"\", \"question\": \"\"\\n3. Start GPT Agent: \"start_agent\", args: \"name\": \"\", \"task\": \"\", \"prompt\": \"\"\\n4. Message GPT Agent: \"message_agent\", args: \"key\": \"\", \"message\": \"\"\\n5. List GPT Agents: \"list_agents\", args:\\n6. Delete GPT Agent: \"delete_agent\", args: \"key\": \"\"\\n7. Clone Repository: \"clone_repository\", args: \"repository_url\": \"\", \"clone_path\": \"\"\\n8. Write to file: \"write_to_file\", args: \"file\": \"\", \"text\": \"\"\\n9. Read file: \"read_file\", args: \"file\": \"\"\\n10. Append to file: \"append_to_file\", args: \"file\": \"\", \"text\": \"\"\\n11. Delete file: \"delete_file\", args: \"file\": \"\"\\n12. Search Files: \"search_files\", args: \"directory\": \"\"\\n13. Analyze Code: \"analyze_code\", args: \"code\": \"\"\\n14. Get Improved Code: \"improve_code\", args: \"suggestions\": \"\", \"code\": \"\"\\n15. Write Tests: \"write_tests\", args: \"code\": \"\", \"focus\": \"\"\\n16. Execute Python File: \"execute_python_file\", args: \"file\": \"\"\\n17. Generate Image: \"generate_image\", args: \"prompt\": \"\"\\n18. Send Tweet: \"send_tweet\", args: \"text\": \"\"\\n19. Do Nothing: \"do_nothing\", args:\\n20. Task Complete (Shutdown): \"task_complete\", args: \"reason\": \"\"\\n\\nResources:\\n1. Internet access for searches and information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\\n2. Constructively self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions and strategies to refine your approach.\\n4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\\n\\nYou should only respond in JSON format as described below\\nResponse Format:\\n{\\n \"thoughts\": {\\n \"text\": \"thought\",\\n \"reasoning\": \"reasoning\",\\n \"plan\": \"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\",\\n \"criticism\": \"constructive self-criticism\",\\n \"speak\": \"thoughts summary to say to user\"\\n },\\n \"command\": {\\n \"name\": \"command name\",\\n \"args\": {\\n \"arg name\": \"value\"\\n }\\n }\\n}\\nEnsure the response can be parsed by Python json.loads\\nGPT-Engineer is another project to create a whole repository of code given a task specified in natural language. The GPT-Engineer is instructed to think over a list of smaller components to build and ask for user input to clarify questions as needed.\\nHere are a sample conversation for task clarification sent to OpenAI ChatCompletion endpoint used by GPT-Engineer. The user inputs are wrapped in {{user input text}}.\\n[\\n {\\n \"role\": \"system\",\\n \"content\": \"You will read instructions and not carry them out, only seek to clarify them.\\\\nSpecifically you will first summarise a list of super short bullets of areas that need clarification.\\\\nThen you will pick one clarifying question, and wait for an answer from the user.\\\\n\"\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"We are writing {{a Super Mario game in python. MVC components split in separate files. Keyboard control.}}\\\\n\"\\n },\\n {\\n \"role\": \"assistant\",\\n \"content\": \"Summary of areas that need clarification:\\\\n1. Specifics of the Super Mario game (e.g. level design, characters, gameplay mechanics)\\\\n2. Details about the MVC components (e.g. which components are in each file)\\\\n3. Keyboard control implementation (e.g. which keys to use, how to handle input)\\\\n\\\\nClarifying question:\\\\nCan you provide more details about the Super Mario game, such as level design, characters, and gameplay mechanics?\"\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"{{There are 10 levels in total. The main character is a plumber named Mario, who can walk and jump. It is a classical platform game just like Super Mario. The main character moves from left to right, trying to get to the destination, where there are many obstacles and attacks from enemies in the process.}}\\\\n\\\\nIs anything else unclear? If yes, only answer in the form:\\\\n{remaining unclear areas} remaining questions.\\\\n{Next question}\\\\nIf everything is sufficiently clear, only answer \\\\\"Nothing more to clarify.\\\\\".\"\\n },\\n {\\n \"role\": \"assistant\",\\n \"content\": \"Remaining unclear areas: 2 remaining questions.\\\\nCan you provide more information about how the MVC components are split into separate files?\"\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"{{Make your own assumptions and state them explicitly before starting}}\"\\n }\\n]\\nThen after these clarification, the agent moved into the code writing mode with a different system message.\\nSystem message:\\n\\nYou will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nMake sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the right decisions to make sure we get it right.\\nYou will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.\\nThen you will output the content of each file including ALL code.\\nEach file must strictly follow a markdown code block format, where the following tokens must be replaced such that\\nFILENAME is the lowercase file name including the file extension,\\nLANG is the markup code block language for the code’s language, and CODE is the code:\\nFILENAME\\nCODE\\nYou will start with the “entrypoint” file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\nUseful to know:\\nYou almost always put different classes in different files.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nYou always add a comment briefly describing the purpose of the function definition.\\nYou try to add comments explaining very complex bits of logic.\\nYou always follow the best practices for the requested languages in terms of describing the code written as a defined\\npackage/project.\\nPython toolbelt preferences:\\n\\npytest\\ndataclasses\\n\\n\\nConversatin samples:\\n[\\n {\\n \"role\": \"system\",\\n \"content\": \"You will get instructions for code to write.\\\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\\\nMake sure that every detail of the architecture is, in the end, implemented as code.\\\\n\\\\nThink step by step and reason yourself to the right decisions to make sure we get it right.\\\\nYou will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.\\\\n\\\\nThen you will output the content of each file including ALL code.\\\\nEach file must strictly follow a markdown code block format, where the following tokens must be replaced such that\\\\nFILENAME is the lowercase file name including the file extension,\\\\nLANG is the markup code block language for the code\\'s language, and CODE is the code:\\\\n\\\\nFILENAME\\\\n```LANG\\\\nCODE\\\\n```\\\\n\\\\nYou will start with the \\\\\"entrypoint\\\\\" file, then go to the ones that are imported by that file, and so on.\\\\nPlease note that the code should be fully functional. No placeholders.\\\\n\\\\nFollow a language and framework appropriate best practice file naming convention.\\\\nMake sure that files contain all imports, types etc. Make sure that code in different files are compatible with each other.\\\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\\\nInclude module dependency or package manager dependency definition file.\\\\nBefore you finish, double check that all parts of the architecture is present in the files.\\\\n\\\\nUseful to know:\\\\nYou almost always put different classes in different files.\\\\nFor Python, you always create an appropriate requirements.txt file.\\\\nFor NodeJS, you always create an appropriate package.json file.\\\\nYou always add a comment briefly describing the purpose of the function definition.\\\\nYou try to add comments explaining very complex bits of logic.\\\\nYou always follow the best practices for the requested languages in terms of describing the code written as a defined\\\\npackage/project.\\\\n\\\\n\\\\nPython toolbelt preferences:\\\\n- pytest\\\\n- dataclasses\\\\n\"\\n },\\n # … same conversation as earlier, ended with \"Make your own assumptions and state them explicitly before starting\".\\n {\\n \"role\": \"assistant\",\\n \"content\": \"Assumptions:\\\\n1. Model: The model will contain the game\\'s data, such as level information, character states, and enemy positions.\\\\n2. View: The view will handle the game\\'s visuals, including rendering the game objects, backgrounds, and updating the display.\\\\n3. Controller: The controller will manage user input, such as keyboard controls, and update the model accordingly.\\\\n\\\\nWith these assumptions in mind, is there any specific aspect of the keyboard control implementation you would like me to clarify?\"\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"Please now remember the steps:\\\\n\\\\nThink step by step and reason yourself to the right decisions to make sure we get it right.\\\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\\\n\\\\nThen you will output the content of each file including ALL code.\\\\nEach file must strictly follow a markdown code block format, where the following tokens must be replaced such that\\\\nFILENAME is the lowercase file name including the file extension,\\\\nLANG is the markup code block language for the code\\'s language, and CODE is the code:\\\\n\\\\nFILENAME\\\\n```LANG\\\\nCODE\\\\n```\\\\n\\\\nPlease note that the code should be fully functional. No placeholders.\\\\n\\\\nYou will start with the \\\\\"entrypoint\\\\\" file, then go to the ones that are imported by that file, and so on.\\\\nFollow a language and framework appropriate best practice file naming convention.\\\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\\\nBefore you finish, double check that all parts of the architecture is present in the files.\\\\n\"\\n }\\n]\\nChallenges#\\nAfter going through key ideas and demos of building LLM-centered agents, I start to see a couple common limitations:\\n\\n\\nFinite context length: The restricted context capacity limits the inclusion of historical information, detailed instructions, API call context, and responses. The design of the system has to work with this limited communication bandwidth, while mechanisms like self-reflection to learn from past mistakes would benefit a lot from long or infinite context windows. Although vector stores and retrieval can provide access to a larger knowledge pool, their representation power is not as powerful as full attention.\\n\\n\\nChallenges in long-term planning and task decomposition: Planning over a lengthy history and effectively exploring the solution space remain challenging. LLMs struggle to adjust plans when faced with unexpected errors, making them less robust compared to humans who learn from trial and error.\\n\\n\\nReliability of natural language interface: Current agent system relies on natural language as an interface between LLMs and external components such as memory and tools. However, the reliability of model outputs is questionable, as LLMs may make formatting errors and occasionally exhibit rebellious behavior (e.g. refuse to follow an instruction). Consequently, much of the agent demo code focuses on parsing model output.\\n\\n\\nCitation#\\nCited as:\\n\\nWeng, Lilian. (Jun 2023). “LLM-powered Autonomous Agents”. Lil’Log. https://lilianweng.github.io/posts/2023-06-23-agent/.\\n\\nOr\\n@article{weng2023agent,\\n title = \"LLM-powered Autonomous Agents\",\\n author = \"Weng, Lilian\",\\n journal = \"lilianweng.github.io\",\\n year = \"2023\",\\n month = \"Jun\",\\n url = \"https://lilianweng.github.io/posts/2023-06-23-agent/\"\\n}\\nReferences#\\n[1] Wei et al. “Chain of thought prompting elicits reasoning in large language models.” NeurIPS 2022\\n[2] Yao et al. “Tree of Thoughts: Dliberate Problem Solving with Large Language Models.” arXiv preprint arXiv:2305.10601 (2023).\\n[3] Liu et al. “Chain of Hindsight Aligns Language Models with Feedback\\n“ arXiv preprint arXiv:2302.02676 (2023).\\n[4] Liu et al. “LLM+P: Empowering Large Language Models with Optimal Planning Proficiency” arXiv preprint arXiv:2304.11477 (2023).\\n[5] Yao et al. “ReAct: Synergizing reasoning and acting in language models.” ICLR 2023.\\n[6] Google Blog. “Announcing ScaNN: Efficient Vector Similarity Search” July 28, 2020.\\n[7] https://chat.openai.com/share/46ff149e-a4c7-4dd7-a800-fc4a642ea389\\n[8] Shinn & Labash. “Reflexion: an autonomous agent with dynamic memory and self-reflection” arXiv preprint arXiv:2303.11366 (2023).\\n[9] Laskin et al. “In-context Reinforcement Learning with Algorithm Distillation” ICLR 2023.\\n[10] Karpas et al. “MRKL Systems A modular, neuro-symbolic architecture that combines large language models, external knowledge sources and discrete reasoning.” arXiv preprint arXiv:2205.00445 (2022).\\n[11] Nakano et al. “Webgpt: Browser-assisted question-answering with human feedback.” arXiv preprint arXiv:2112.09332 (2021).\\n[12] Parisi et al. “TALM: Tool Augmented Language Models”\\n[13] Schick et al. “Toolformer: Language Models Can Teach Themselves to Use Tools.” arXiv preprint arXiv:2302.04761 (2023).\\n[14] Weaviate Blog. Why is Vector Search so fast? Sep 13, 2022.\\n[15] Li et al. “API-Bank: A Benchmark for Tool-Augmented LLMs” arXiv preprint arXiv:2304.08244 (2023).\\n[16] Shen et al. “HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in HuggingFace” arXiv preprint arXiv:2303.17580 (2023).\\n[17] Bran et al. “ChemCrow: Augmenting large-language models with chemistry tools.” arXiv preprint arXiv:2304.05376 (2023).\\n[18] Boiko et al. “Emergent autonomous scientific research capabilities of large language models.” arXiv preprint arXiv:2304.05332 (2023).\\n[19] Joon Sung Park, et al. “Generative Agents: Interactive Simulacra of Human Behavior.” arXiv preprint arXiv:2304.03442 (2023).\\n[20] AutoGPT. https://github.com/Significant-Gravitas/Auto-GPT\\n[21] GPT-Engineer. https://github.com/AntonOsika/gpt-engineer\\n\\n\\n\\nnlp\\nlanguage-model\\nagent\\nsteerability\\nprompting\\n\\n\\n\\n« \\n\\nAdversarial Attacks on LLMs\\n\\n\\n »\\n\\nPrompt Engineering\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n© 2024 Lil\\'Log\\n\\n Powered by\\n Hugo &\\n PaperMod\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n', metadata={'source': 'https://lilianweng.github.io/posts/2023-06-23-agent/', 'title': \"LLM Powered Autonomous Agents | Lil'Log\", 'description': 'Building agents with LLM (large language model) as its core controller is a cool concept. Several proof-of-concepts demos, such as AutoGPT, GPT-Engineer and BabyAGI, serve as inspiring examples. The potentiality of LLM extends beyond generating well-written copies, stories, essays and programs; it can be framed as a powerful general problem solver.\\nAgent System Overview In a LLM-powered autonomous agent system, LLM functions as the agent’s brain, complemented by several key components:', 'language': 'en'})]"
259 | ]
260 | },
261 | "execution_count": 14,
262 | "metadata": {},
263 | "output_type": "execute_result"
264 | }
265 | ],
266 | "source": [
267 | "docs"
268 | ]
269 | },
270 | {
271 | "cell_type": "code",
272 | "execution_count": 18,
273 | "metadata": {},
274 | "outputs": [
275 | {
276 | "name": "stdout",
277 | "output_type": "stream",
278 | "text": [
279 | "\n",
280 | "\n",
281 | "\n",
282 | "\n",
283 | "\n",
284 | "\n",
285 | "LLM Powered Autonomous Agents | Lil'Log\n",
286 | "\n",
287 | "\n",
288 | "\n",
289 | "\n",
290 | "\n",
291 | "\n",
292 | "\n",
293 | "\n",
294 | "\n",
295 | "\n",
296 | "\n",
297 | "\n",
298 | "\n",
299 | "\n",
300 | "\n",
301 | "\n",
302 | "\n",
303 | "\n",
304 | "\n",
305 | "\n",
306 | "\n",
307 | "\n",
308 | "\n",
309 | "\n",
310 | "\n",
311 | "\n",
312 | "\n",
313 | "\n",
314 | "\n",
315 | "\n",
316 | "\n",
317 | "\n",
318 | "\n",
319 | "\n",
320 | "\n",
321 | "\n",
322 | "\n",
323 | "\n",
324 | "\n",
325 | "Lil'Log\n",
326 | "\n",
327 | "\n",
328 | "\n",
329 | "\n",
330 | "\n",
331 | "\n",
332 | "\n",
333 | "\n",
334 | "\n",
335 | "\n",
336 | "\n",
337 | "\n",
338 | "\n",
339 | "\n",
340 | "\n",
341 | "\n",
342 | "\n",
343 | "\n",
344 | "\n",
345 | "\n",
346 | "\n",
347 | "\n",
348 | "Posts\n",
349 | "\n",
350 | "\n",
351 | "\n",
352 | "\n",
353 | "Archive\n",
354 | "\n",
355 | "\n",
356 | "\n",
357 | "\n",
358 | "Search\n",
359 | "\n",
360 | "\n",
361 | "\n",
362 | "\n",
363 | "Tags\n",
364 | "\n",
365 | "\n",
366 | "\n",
367 | "\n",
368 | "FAQ\n",
369 | "\n",
370 | "\n",
371 | "\n",
372 | "\n",
373 | "emojisearch.app\n",
374 | "\n",
375 | "\n",
376 | "\n",
377 | "\n",
378 | "\n",
379 | "\n",
380 | "\n",
381 | "\n",
382 | "\n",
383 | " LLM Powered Autonomous Agents\n",
384 | " \n",
385 | "Date: June 23, 2023 | Estimated Reading Time: 31 min | Author: Lilian Weng\n",
386 | "\n",
387 | "\n",
388 | " \n",
389 | "\n",
390 | "\n",
391 | "Table of Contents\n",
392 | "\n",
393 | "\n",
394 | "\n",
395 | "Agent System Overview\n",
396 | "\n",
397 | "Component One: Planning\n",
398 | "\n",
399 | "Task Decomposition\n",
400 | "\n",
401 | "Self-Reflection\n",
402 | "\n",
403 | "\n",
404 | "Component Two: Memory\n",
405 | "\n",
406 | "Types of Memory\n",
407 | "\n",
408 | "Maximum Inner Product Search (MIPS)\n",
409 | "\n",
410 | "\n",
411 | "Component Three: Tool Use\n",
412 | "\n",
413 | "Case Studies\n",
414 | "\n",
415 | "Scientific Discovery Agent\n",
416 | "\n",
417 | "Generative Agents Simulation\n",
418 | "\n",
419 | "Proof-of-Concept Examples\n",
420 | "\n",
421 | "\n",
422 | "Challenges\n",
423 | "\n",
424 | "Citation\n",
425 | "\n",
426 | "References\n",
427 | "\n",
428 | "\n",
429 | "\n",
430 | "\n",
431 | "\n",
432 | "Building agents with LLM (large language model) as its core controller is a cool concept. Several proof-of-concepts demos, such as AutoGPT, GPT-Engineer and BabyAGI, serve as inspiring examples. The potentiality of LLM extends beyond generating well-written copies, stories, essays and programs; it can be framed as a powerful general problem solver.\n",
433 | "Agent System Overview#\n",
434 | "In a LLM-powered autonomous agent system, LLM functions as the agent’s brain, complemented by several key components:\n",
435 | "\n",
436 | "Planning\n",
437 | "\n",
438 | "Subgoal and decomposition: The agent breaks down large tasks into smaller, manageable subgoals, enabling efficient handling of complex tasks.\n",
439 | "Reflection and refinement: The agent can do self-criticism and self-reflection over past actions, learn from mistakes and refine them for future steps, thereby improving the quality of final results.\n",
440 | "\n",
441 | "\n",
442 | "Memory\n",
443 | "\n",
444 | "Short-term memory: I would consider all the in-context learning (See Prompt Engineering) as utilizing short-term memory of the model to learn.\n",
445 | "Long-term memory: This provides the agent with the capability to retain and recall (infinite) information over extended periods, often by leveraging an external vector store and fast retrieval.\n",
446 | "\n",
447 | "\n",
448 | "Tool use\n",
449 | "\n",
450 | "The agent learns to call external APIs for extra information that is missing from the model weights (often hard to change after pr\n"
451 | ]
452 | }
453 | ],
454 | "source": [
455 | "print(docs[0].page_content[:2000])"
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": 19,
461 | "metadata": {},
462 | "outputs": [],
463 | "source": [
464 | "llm = ChatOpenAI(temperature=0, model_name=\"gpt-3.5-turbo-1106\")\n",
465 | "chain = load_summarize_chain(llm, chain_type=\"stuff\")"
466 | ]
467 | },
468 | {
469 | "cell_type": "code",
470 | "execution_count": 21,
471 | "metadata": {},
472 | "outputs": [
473 | {
474 | "data": {
475 | "text/plain": [
476 | "StuffDocumentsChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['text'], template='Write a concise summary of the following:\\n\\n\\n\"{text}\"\\n\\n\\nCONCISE SUMMARY:'), llm=ChatOpenAI(client=, async_client=, model_name='gpt-3.5-turbo-1106', temperature=0.0, openai_api_key=SecretStr('**********'), openai_proxy='')), document_variable_name='text')"
477 | ]
478 | },
479 | "execution_count": 21,
480 | "metadata": {},
481 | "output_type": "execute_result"
482 | }
483 | ],
484 | "source": [
485 | "chain"
486 | ]
487 | },
488 | {
489 | "cell_type": "code",
490 | "execution_count": 22,
491 | "metadata": {},
492 | "outputs": [
493 | {
494 | "name": "stdout",
495 | "output_type": "stream",
496 | "text": [
497 | "The article discusses the concept of LLM-powered autonomous agents, which use large language models as their core controllers. It covers the components of these agents, including planning, memory, and tool use, as well as case studies and proof-of-concept examples. The challenges and limitations of using natural language interfaces for these agents are also discussed. The article provides citations and references for further reading.\n"
498 | ]
499 | }
500 | ],
501 | "source": [
502 | "result = chain.invoke(docs)\n",
503 | "\n",
504 | "print(result[\"output_text\"])"
505 | ]
506 | },
507 | {
508 | "cell_type": "code",
509 | "execution_count": 23,
510 | "metadata": {},
511 | "outputs": [
512 | {
513 | "name": "stderr",
514 | "output_type": "stream",
515 | "text": [
516 | "/opt/anaconda3/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 0.3.0. Use RunnableSequence, e.g., `prompt | llm` instead.\n",
517 | " warn_deprecated(\n"
518 | ]
519 | },
520 | {
521 | "name": "stdout",
522 | "output_type": "stream",
523 | "text": [
524 | "The article discusses the concept of building autonomous agents powered by large language models (LLMs). It explores the components of such agents, including planning, memory, and tool use. The article provides case studies and examples of proof-of-concept demos, highlighting the challenges and limitations of LLM-powered agents. It also includes citations and references for further reading.\n"
525 | ]
526 | }
527 | ],
528 | "source": [
529 | "# Define prompt\n",
530 | "prompt = PromptTemplate.from_template(prompt_template)\n",
531 | "\n",
532 | "# Define LLM chain\n",
533 | "llm = ChatOpenAI(temperature=0, model_name=\"gpt-3.5-turbo-16k\")\n",
534 | "llm_chain = LLMChain(llm=llm, prompt=prompt)\n",
535 | "\n",
536 | "# Define StuffDocumentsChain\n",
537 | "stuff_chain = StuffDocumentsChain(llm_chain=llm_chain, document_variable_name=\"text\")\n",
538 | "\n",
539 | "docs = loader.load()\n",
540 | "print(stuff_chain.invoke(docs)[\"output_text\"])"
541 | ]
542 | },
543 | {
544 | "cell_type": "markdown",
545 | "metadata": {},
546 | "source": [
547 | "## Using MapReduce"
548 | ]
549 | },
550 | {
551 | "cell_type": "code",
552 | "execution_count": 24,
553 | "metadata": {},
554 | "outputs": [],
555 | "source": [
556 | "llm = ChatOpenAI(temperature=0.7)"
557 | ]
558 | },
559 | {
560 | "cell_type": "markdown",
561 | "metadata": {},
562 | "source": [
563 | "Map"
564 | ]
565 | },
566 | {
567 | "cell_type": "code",
568 | "execution_count": 25,
569 | "metadata": {},
570 | "outputs": [],
571 | "source": [
572 | "map_template = \"\"\"The following is a set of documents\n",
573 | "{docs}\n",
574 | "Based on this list of docs, please identify the main themes \n",
575 | "Helpful Answer:\"\"\""
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "execution_count": 26,
581 | "metadata": {},
582 | "outputs": [],
583 | "source": [
584 | "map_prompt = PromptTemplate.from_template(map_template)\n",
585 | "map_chain = LLMChain(llm=llm, prompt=map_prompt)"
586 | ]
587 | },
588 | {
589 | "cell_type": "markdown",
590 | "metadata": {},
591 | "source": [
592 | "Reduce"
593 | ]
594 | },
595 | {
596 | "cell_type": "code",
597 | "execution_count": 28,
598 | "metadata": {},
599 | "outputs": [],
600 | "source": [
601 | "reduce_template = \"\"\"The following is set of summaries:\n",
602 | "{docs}\n",
603 | "Take these and distill it into a final, consolidated summary of the main themes. \n",
604 | "Helpful Answer:\"\"\"\n",
605 | "reduce_prompt = PromptTemplate.from_template(reduce_template)"
606 | ]
607 | },
608 | {
609 | "cell_type": "markdown",
610 | "metadata": {},
611 | "source": [
612 | "Run chain"
613 | ]
614 | },
615 | {
616 | "cell_type": "code",
617 | "execution_count": 29,
618 | "metadata": {},
619 | "outputs": [],
620 | "source": [
621 | "reduce_chain = LLMChain(llm=llm, prompt=reduce_prompt)"
622 | ]
623 | },
624 | {
625 | "cell_type": "code",
626 | "execution_count": 30,
627 | "metadata": {},
628 | "outputs": [],
629 | "source": [
630 | "# Takes a list of documents, combines them into a single string, and passes this to an LLMChain\n",
631 | "combine_documents_chain = StuffDocumentsChain(\n",
632 | " llm_chain=reduce_chain, document_variable_name=\"docs\"\n",
633 | ")"
634 | ]
635 | },
636 | {
637 | "cell_type": "markdown",
638 | "metadata": {},
639 | "source": [
640 | "Iteratively reduces the mapped documents"
641 | ]
642 | },
643 | {
644 | "cell_type": "code",
645 | "execution_count": 31,
646 | "metadata": {},
647 | "outputs": [],
648 | "source": [
649 | "reduce_documents_chain = ReduceDocumentsChain(\n",
650 | " # This is final chain that is called.\n",
651 | " combine_documents_chain=combine_documents_chain,\n",
652 | " # If documents exceed context for `StuffDocumentsChain`\n",
653 | " collapse_documents_chain=combine_documents_chain,\n",
654 | " # The maximum number of tokens to group documents into.\n",
655 | " token_max=4000,\n",
656 | ")"
657 | ]
658 | },
659 | {
660 | "cell_type": "markdown",
661 | "metadata": {},
662 | "source": [
663 | "Full MapReduce chain"
664 | ]
665 | },
666 | {
667 | "cell_type": "code",
668 | "execution_count": 32,
669 | "metadata": {},
670 | "outputs": [],
671 | "source": [
672 | "map_reduce_chain = MapReduceDocumentsChain(\n",
673 | " # Map chain\n",
674 | " llm_chain=map_chain,\n",
675 | " # Reduce chain\n",
676 | " reduce_documents_chain=reduce_documents_chain,\n",
677 | " # The variable name in the llm_chain to put the documents in\n",
678 | " document_variable_name=\"docs\",\n",
679 | " # Return the results of the map steps in the output\n",
680 | " return_intermediate_steps=False,\n",
681 | ")"
682 | ]
683 | },
684 | {
685 | "cell_type": "code",
686 | "execution_count": 33,
687 | "metadata": {},
688 | "outputs": [
689 | {
690 | "name": "stderr",
691 | "output_type": "stream",
692 | "text": [
693 | "Created a chunk of size 1003, which is longer than the specified 1000\n"
694 | ]
695 | }
696 | ],
697 | "source": [
698 | "text_splitter = CharacterTextSplitter.from_tiktoken_encoder(\n",
699 | " chunk_size = 1000, \n",
700 | " chunk_overlap = 0\n",
701 | ")\n",
702 | "\n",
703 | "split_docs = text_splitter.split_documents(docs)"
704 | ]
705 | },
706 | {
707 | "cell_type": "code",
708 | "execution_count": 35,
709 | "metadata": {},
710 | "outputs": [
711 | {
712 | "data": {
713 | "text/plain": [
714 | "langchain_core.documents.base.Document"
715 | ]
716 | },
717 | "execution_count": 35,
718 | "metadata": {},
719 | "output_type": "execute_result"
720 | }
721 | ],
722 | "source": [
723 | "type(split_docs[0])"
724 | ]
725 | },
726 | {
727 | "cell_type": "code",
728 | "execution_count": 36,
729 | "metadata": {},
730 | "outputs": [
731 | {
732 | "name": "stdout",
733 | "output_type": "stream",
734 | "text": [
735 | "14\n"
736 | ]
737 | }
738 | ],
739 | "source": [
740 | "print(len(split_docs))"
741 | ]
742 | },
743 | {
744 | "cell_type": "code",
745 | "execution_count": 37,
746 | "metadata": {},
747 | "outputs": [
748 | {
749 | "name": "stdout",
750 | "output_type": "stream",
751 | "text": [
752 | "You will get instructions for code to write.\n",
753 | "You will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\n",
754 | "Make sure that every detail of the architecture is, in the end, implemented as code.\n",
755 | "Think step by step and reason yourself to the right decisions to make sure we get it right.\n",
756 | "You will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.\n",
757 | "Then you will output the content of each file including ALL code.\n",
758 | "Each file must strictly follow a markdown code block format, where the following tokens must be replaced such that\n",
759 | "FILENAME is the lowercase file name including the file extension,\n",
760 | "LANG is the markup code block language for the code’s language, and CODE is the code:\n",
761 | "FILENAME\n",
762 | "CODE\n",
763 | "You will start with the “entrypoint” file, then go to the ones that are imported by that file, and so on.\n",
764 | "Please note that the code should be fully functional. No placeholders.\n",
765 | "Follow a language and framework appropriate best practice file naming convention.\n",
766 | "Make sure that files contain all imports, types etc. Make sure that code in different files are compatible with each other.\n",
767 | "Ensure to implement all code, if you are unsure, write a plausible implementation.\n",
768 | "Include module dependency or package manager dependency definition file.\n",
769 | "Before you finish, double check that all parts of the architecture is present in the files.\n",
770 | "Useful to know:\n",
771 | "You almost always put different classes in different files.\n",
772 | "For Python, you always create an appropriate requirements.txt file.\n",
773 | "For NodeJS, you always create an appropriate package.json file.\n",
774 | "You always add a comment briefly describing the purpose of the function definition.\n",
775 | "You try to add comments explaining very complex bits of logic.\n",
776 | "You always follow the best practices for the requested languages in terms of describing the code written as a defined\n",
777 | "package/project.\n",
778 | "Python toolbelt preferences:\n",
779 | "\n",
780 | "pytest\n",
781 | "dataclasses\n"
782 | ]
783 | }
784 | ],
785 | "source": [
786 | "print(split_docs[10].page_content)"
787 | ]
788 | },
789 | {
790 | "cell_type": "markdown",
791 | "metadata": {},
792 | "source": [
793 | "# Information Extraction"
794 | ]
795 | },
796 | {
797 | "cell_type": "markdown",
798 | "metadata": {},
799 | "source": [
800 | "Based on https://python.langchain.com/v0.1/docs/use_cases/extraction/quickstart/\n",
801 | "\n",
802 | "We start by loading a number of tweets from a csv file"
803 | ]
804 | },
805 | {
806 | "cell_type": "code",
807 | "execution_count": 38,
808 | "metadata": {},
809 | "outputs": [
810 | {
811 | "data": {
812 | "text/html": [
813 | "\n",
814 | "\n",
827 | "
\n",
828 | " \n",
829 | " \n",
830 | " | \n",
831 | " text | \n",
832 | " created_at | \n",
833 | " id_str | \n",
834 | "
\n",
835 | " \n",
836 | " \n",
837 | " \n",
838 | " 0 | \n",
839 | " .@FoxNews is no longer the same. We miss the g... | \n",
840 | " 05-19-2020 01:59:49 | \n",
841 | " 1262563582086184970 | \n",
842 | "
\n",
843 | " \n",
844 | " 1 | \n",
845 | " So the so-called HHS Whistleblower was against... | \n",
846 | " 05-18-2020 14:44:21 | \n",
847 | " 1262393595560067073 | \n",
848 | "
\n",
849 | " \n",
850 | " 2 | \n",
851 | " .....mixed about even wanting us to get out. T... | \n",
852 | " 05-18-2020 14:39:40 | \n",
853 | " 1262392415513690112 | \n",
854 | "
\n",
855 | " \n",
856 | " 3 | \n",
857 | " Wow! The Front Page @washingtonpost Headline r... | \n",
858 | " 05-18-2020 12:47:40 | \n",
859 | " 1262364231288197123 | \n",
860 | "
\n",
861 | " \n",
862 | " 4 | \n",
863 | " MAGA crowds are bigger than ever! https://t.co... | \n",
864 | " 05-18-2020 12:26:37 | \n",
865 | " 1262358931982123008 | \n",
866 | "
\n",
867 | " \n",
868 | "
\n",
869 | "
"
870 | ],
871 | "text/plain": [
872 | " text created_at \\\n",
873 | "0 .@FoxNews is no longer the same. We miss the g... 05-19-2020 01:59:49 \n",
874 | "1 So the so-called HHS Whistleblower was against... 05-18-2020 14:44:21 \n",
875 | "2 .....mixed about even wanting us to get out. T... 05-18-2020 14:39:40 \n",
876 | "3 Wow! The Front Page @washingtonpost Headline r... 05-18-2020 12:47:40 \n",
877 | "4 MAGA crowds are bigger than ever! https://t.co... 05-18-2020 12:26:37 \n",
878 | "\n",
879 | " id_str \n",
880 | "0 1262563582086184970 \n",
881 | "1 1262393595560067073 \n",
882 | "2 1262392415513690112 \n",
883 | "3 1262364231288197123 \n",
884 | "4 1262358931982123008 "
885 | ]
886 | },
887 | "execution_count": 38,
888 | "metadata": {},
889 | "output_type": "execute_result"
890 | }
891 | ],
892 | "source": [
893 | "data = pd.read_csv('data/trump.csv')\n",
894 | "data.head()"
895 | ]
896 | },
897 | {
898 | "cell_type": "code",
899 | "execution_count": 39,
900 | "metadata": {},
901 | "outputs": [
902 | {
903 | "data": {
904 | "text/plain": [
905 | "(2834, 3)"
906 | ]
907 | },
908 | "execution_count": 39,
909 | "metadata": {},
910 | "output_type": "execute_result"
911 | }
912 | ],
913 | "source": [
914 | "data.shape"
915 | ]
916 | },
917 | {
918 | "cell_type": "markdown",
919 | "metadata": {},
920 | "source": [
921 | "And defining the data structures that will hold the data we want our chain to extract. The comments help the LLM understand what each field means"
922 | ]
923 | },
924 | {
925 | "cell_type": "code",
926 | "execution_count": 42,
927 | "metadata": {},
928 | "outputs": [],
929 | "source": [
930 | "class Person(BaseModel):\n",
931 | " \"\"\"Information about a person.\"\"\"\n",
932 | " name: Optional[str] = Field(default=None, description=\"The name of the person\")\n",
933 | " twitter_handle: Optional[str] = Field(\n",
934 | " default=None, description=\"The twitter handle if known\"\n",
935 | " )\n",
936 | "\n",
937 | "class Data(BaseModel):\n",
938 | " \"\"\"Extracted data about people.\"\"\"\n",
939 | "\n",
940 | " # Creates a model so that we can extract multiple entities.\n",
941 | " people: List[Person]"
942 | ]
943 | },
944 | {
945 | "cell_type": "code",
946 | "execution_count": 43,
947 | "metadata": {},
948 | "outputs": [],
949 | "source": [
950 | "prompt = ChatPromptTemplate.from_messages(\n",
951 | " [\n",
952 | " (\n",
953 | " \"system\",\n",
954 | " \"You are an expert data extraction algorithm. \"\n",
955 | " \"Only extract relevant information from the text. \"\n",
956 | " \"If you do not know the value of an attribute asked to extract, \"\n",
957 | " \"return null for the attribute's value.\",\n",
958 | " ),\n",
959 | " (\"human\", \"{text}\"),\n",
960 | " ]\n",
961 | ")"
962 | ]
963 | },
964 | {
965 | "cell_type": "markdown",
966 | "metadata": {},
967 | "source": [
968 | "and our chain"
969 | ]
970 | },
971 | {
972 | "cell_type": "code",
973 | "execution_count": 44,
974 | "metadata": {},
975 | "outputs": [],
976 | "source": [
977 | "runnable = prompt | llm.with_structured_output(schema=Data)"
978 | ]
979 | },
980 | {
981 | "cell_type": "code",
982 | "execution_count": 46,
983 | "metadata": {},
984 | "outputs": [
985 | {
986 | "name": "stdout",
987 | "output_type": "stream",
988 | "text": [
989 | "0 ==> .@FoxNews is no longer the same. We miss the great Roger Ailes. You have more anti-Trump people by far than ever before. Looking for a new outlet! https://t.co/jXxsF0flUM people=[Person(name='Roger Ailes', twitter_handle=None)]\n",
990 | "1 ==> So the so-called HHS Whistleblower was against HYDROXYCHLOROQUINE. Then why did he make and sign an emergency use authorization? @NorahODonnell said “He shared his concerns with a reporter.” In other words he LEAKED. A dumb @60Minutes hit job on a grandstanding Never Trumper! people=[Person(name=\"Norah O'Donnell\", twitter_handle='NorahODonnell')]\n",
991 | "2 ==> .....mixed about even wanting us to get out. They make a fortune $$$ by having us stay and except at the beginning we never really fought to win. We are more of a police force than the mighty military that we are especially now as rebuilt. No I am not acting impulsively! people=[Person(name='unknown', twitter_handle=None)]\n",
992 | "3 ==> Wow! The Front Page @washingtonpost Headline reads “A BOOST IN TESTS BUT LACK OF TAKERS.” We have done a great job on Ventilators Testing and everything else. Were left little by Obama. Over 11 million tests and going up fast. More than all countries in the world combined. people=[Person(name='Obama', twitter_handle=None)]\n",
993 | "4 ==> MAGA crowds are bigger than ever! https://t.co/zKxoTBw02v people=[Person(name='MAGA crowds', twitter_handle=None)]\n",
994 | "5 ==> ....spews lies. @60Minutes report was incorrect which they couldn’t care less about. Fake News! I don’t know this guy never met him but don’t like what I see. How can a creep like this show up to work tomorrow & report to @SecAzar his boss after trashing him on T.V.?.... people=[Person(name=None, twitter_handle='SecAzar')]\n",
995 | "6 ==> .@60Minutes & third place anchor @NorahODonnell are doing everything in their power to demean our Country much to the benefit of the Radical Left Democrats. Tonight they put on yet another Fake “Whistleblower” a disgruntled employee who supports Dems fabricates stories &... people=[Person(name=\"Norah O'Donnell\", twitter_handle=None)]\n",
996 | "7 ==> Thank you very much to our beautiful “boaters.” I will never let you down! #MAGA https://t.co/BiqIqzgOcL people=[Person(name='boaters', twitter_handle=None)]\n",
997 | "8 ==> .....are therefore given massive advantages over The United States and everyone else? Prior to the Plague floating in from China our Economy was blowing everybody away the best of any country EVER. We will be there again and soon! people=[Person(name='The United States', twitter_handle=None)]\n",
998 | "9 ==> I’m not running against Sleepy Joe Biden. He is not even a factor. Never was remember 1% Joe? I’m running against the Radical Left Do Nothing Democrats & their partner the real opposition party the Lamestream Fake News Media! They are vicious & crazy but we will WIN! https://t.co/ltdHSmaMYT people=[Person(name='Sleepy Joe Biden', twitter_handle=None)]\n"
999 | ]
1000 | }
1001 | ],
1002 | "source": [
1003 | "for i, tweet in enumerate(data['text'].head(10)):\n",
1004 | " response = runnable.invoke({\"text\": tweet})\n",
1005 | " print(i, '==>', tweet, response)"
1006 | ]
1007 | },
1008 | {
1009 | "cell_type": "markdown",
1010 | "metadata": {},
1011 | "source": [
1012 | "\n",
1013 | "
\n",
1014 | ""
1015 | ]
1016 | }
1017 | ],
1018 | "metadata": {
1019 | "kernelspec": {
1020 | "display_name": "Python 3 (ipykernel)",
1021 | "language": "python",
1022 | "name": "python3"
1023 | },
1024 | "language_info": {
1025 | "codemirror_mode": {
1026 | "name": "ipython",
1027 | "version": 3
1028 | },
1029 | "file_extension": ".py",
1030 | "mimetype": "text/x-python",
1031 | "name": "python",
1032 | "nbconvert_exporter": "python",
1033 | "pygments_lexer": "ipython3",
1034 | "version": "3.11.7"
1035 | },
1036 | "toc": {
1037 | "base_numbering": 1,
1038 | "nav_menu": {},
1039 | "number_sections": true,
1040 | "sideBar": true,
1041 | "skip_h1_title": true,
1042 | "title_cell": "Table of Contents",
1043 | "title_sidebar": "Contents",
1044 | "toc_cell": false,
1045 | "toc_position": {},
1046 | "toc_section_display": true,
1047 | "toc_window_display": false
1048 | },
1049 | "varInspector": {
1050 | "cols": {
1051 | "lenName": 16,
1052 | "lenType": 16,
1053 | "lenVar": 40
1054 | },
1055 | "kernels_config": {
1056 | "python": {
1057 | "delete_cmd_postfix": "",
1058 | "delete_cmd_prefix": "del ",
1059 | "library": "var_list.py",
1060 | "varRefreshCmd": "print(var_dic_list())"
1061 | },
1062 | "r": {
1063 | "delete_cmd_postfix": ") ",
1064 | "delete_cmd_prefix": "rm(",
1065 | "library": "var_list.r",
1066 | "varRefreshCmd": "cat(var_dic_list()) "
1067 | }
1068 | },
1069 | "types_to_exclude": [
1070 | "module",
1071 | "function",
1072 | "builtin_function_or_method",
1073 | "instance",
1074 | "_Feature"
1075 | ],
1076 | "window_display": false
1077 | }
1078 | },
1079 | "nbformat": 4,
1080 | "nbformat_minor": 4
1081 | }
1082 |
--------------------------------------------------------------------------------
/4. ChatBots.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "
\n",
9 | "
LangChain for Generative AI
\n",
10 | "
ChatBot
\n",
11 | "
Bruno Gonçalves
\n",
12 | " www.data4sci.com
\n",
13 | " @bgoncalves, @data4sci
\n",
14 | "
"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from collections import Counter\n",
24 | "from pprint import pprint\n",
25 | "\n",
26 | "import pandas as pd\n",
27 | "import numpy as np\n",
28 | "import matplotlib.pyplot as plt \n",
29 | "\n",
30 | "import langchain\n",
31 | "\n",
32 | "from langchain.prompts import PromptTemplate\n",
33 | "from langchain.document_loaders import GutenbergLoader\n",
34 | "\n",
35 | "from langchain.memory import ConversationBufferMemory\n",
36 | "from langchain.memory.chat_message_histories.in_memory import ChatMessageHistory\n",
37 | "\n",
38 | "from langchain.schema import messages_from_dict, messages_to_dict\n",
39 | "\n",
40 | "from langchain.agents import Tool\n",
41 | "from langchain.agents import initialize_agent\n",
42 | "from langchain.agents import AgentType\n",
43 | "\n",
44 | "from langchain.chains import LLMChain, ConversationalRetrievalChain, ConversationChain\n",
45 | "from langchain.chains import RetrievalQA\n",
46 | "\n",
47 | "from langchain.text_splitter import CharacterTextSplitter\n",
48 | "from langchain.embeddings import HuggingFaceEmbeddings\n",
49 | "from langchain.vectorstores import Chroma\n",
50 | "\n",
51 | "import langchain_openai\n",
52 | "from langchain_openai import ChatOpenAI\n",
53 | "\n",
54 | "import tempfile\n",
55 | "\n",
56 | "import watermark\n",
57 | "\n",
58 | "%load_ext watermark\n",
59 | "%matplotlib inline"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "We start by print out the versions of the libraries we're using for future reference"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 2,
72 | "metadata": {},
73 | "outputs": [
74 | {
75 | "name": "stdout",
76 | "output_type": "stream",
77 | "text": [
78 | "Python implementation: CPython\n",
79 | "Python version : 3.11.7\n",
80 | "IPython version : 8.12.3\n",
81 | "\n",
82 | "Compiler : Clang 14.0.6 \n",
83 | "OS : Darwin\n",
84 | "Release : 23.6.0\n",
85 | "Machine : arm64\n",
86 | "Processor : arm\n",
87 | "CPU cores : 16\n",
88 | "Architecture: 64bit\n",
89 | "\n",
90 | "Git hash: 0b932bf32c4e9b1e4ff9126fc7e8e7ac7b4205ff\n",
91 | "\n",
92 | "json : 2.0.9\n",
93 | "watermark : 2.4.3\n",
94 | "langchain_openai: 0.1.8\n",
95 | "matplotlib : 3.8.0\n",
96 | "langchain : 0.2.2\n",
97 | "pandas : 2.2.3\n",
98 | "numpy : 1.26.4\n",
99 | "\n"
100 | ]
101 | }
102 | ],
103 | "source": [
104 | "%watermark -n -v -m -g -iv"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "Load default figure style"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": 3,
117 | "metadata": {},
118 | "outputs": [],
119 | "source": [
120 | "plt.style.use('./d4sci.mplstyle')"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {},
126 | "source": [
127 | "# Start"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": 5,
133 | "metadata": {},
134 | "outputs": [],
135 | "source": [
136 | "cache_dir = \"./cache\""
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": 6,
142 | "metadata": {},
143 | "outputs": [
144 | {
145 | "data": {
146 | "text/plain": [
147 | "'The Project Gutenberg eBook of Romeo and Juliet This ebook is for the use of anyone anywhere in the United States and most other parts of the world at no cost and with almost no restrictions whatsoever. You may copy it, give it away or re-use it under the terms of the Project Gutenberg License included with this ebook or online at www.gutenberg.org. If you are not located in the United States, you will have to check the laws of the country where you are located before using this eBook. Title: Romeo and Juliet Author: William Shakespeare Release date: November .......'"
148 | ]
149 | },
150 | "metadata": {},
151 | "output_type": "display_data"
152 | }
153 | ],
154 | "source": [
155 | "loader = GutenbergLoader(\n",
156 | " \"https://www.gutenberg.org/cache/epub/1513/pg1513.txt\"\n",
157 | ")\n",
158 | "\n",
159 | "document = loader.load()\n",
160 | "\n",
161 | "extrait = ' '.join(document[0].page_content.split()[:100])\n",
162 | "display(extrait + \" .......\")"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": 7,
168 | "metadata": {},
169 | "outputs": [],
170 | "source": [
171 | "text_splitter = CharacterTextSplitter(\n",
172 | " chunk_size=1024, # Each chunk is of size 1024\n",
173 | " chunk_overlap=128 # Neigboring chunks overlap by 128 characters\n",
174 | ") \n",
175 | "\n",
176 | "texts = text_splitter.split_documents(document)"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": 8,
182 | "metadata": {},
183 | "outputs": [
184 | {
185 | "name": "stderr",
186 | "output_type": "stream",
187 | "text": [
188 | "/opt/anaconda3/lib/python3.11/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
189 | " from tqdm.autonotebook import tqdm, trange\n",
190 | "/opt/anaconda3/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n",
191 | " warnings.warn(\n"
192 | ]
193 | }
194 | ],
195 | "source": [
196 | "model_name = \"sentence-transformers/all-MiniLM-L6-v2\"\n",
197 | "\n",
198 | "embeddings = HuggingFaceEmbeddings(\n",
199 | " model_name=model_name, \n",
200 | " cache_folder=cache_dir\n",
201 | ") # Use a pre-cached model"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": 9,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "vectordb = Chroma.from_documents(\n",
211 | " texts, \n",
212 | " embeddings, \n",
213 | " persist_directory=cache_dir\n",
214 | ")"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": 10,
220 | "metadata": {},
221 | "outputs": [],
222 | "source": [
223 | "question = \"Romeo!\"\n",
224 | "\n",
225 | "docs = vectordb.similarity_search(question, k=2)"
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": 11,
231 | "metadata": {},
232 | "outputs": [
233 | {
234 | "name": "stdout",
235 | "output_type": "stream",
236 | "text": [
237 | "2\n"
238 | ]
239 | }
240 | ],
241 | "source": [
242 | "# Check the length of the document\n",
243 | "print(len(docs))"
244 | ]
245 | },
246 | {
247 | "cell_type": "code",
248 | "execution_count": 12,
249 | "metadata": {},
250 | "outputs": [
251 | {
252 | "name": "stdout",
253 | "output_type": "stream",
254 | "text": [
255 | "Romeo! My cousin Romeo! Romeo!\r\n",
256 | "\n",
257 | "\n",
258 | "\r\n",
259 | "\n",
260 | "\n",
261 | "MERCUTIO.\r\n",
262 | "\n",
263 | "\n",
264 | "He is wise,\r\n",
265 | "\n",
266 | "\n",
267 | "And on my life hath stol’n him home to bed.\r\n",
268 | "\n",
269 | "\n",
270 | "\r\n",
271 | "\n",
272 | "\n",
273 | "BENVOLIO.\r\n",
274 | "\n",
275 | "\n",
276 | "He ran this way, and leap’d this orchard wall:\r\n",
277 | "\n",
278 | "\n",
279 | "Call, good Mercutio.\r\n",
280 | "\n",
281 | "\n",
282 | "\r\n",
283 | "\n",
284 | "\n",
285 | "MERCUTIO.\r\n",
286 | "\n",
287 | "\n",
288 | "Nay, I’ll conjure too.\n",
289 | "====================\n",
290 | "Romeo! My cousin Romeo! Romeo!\r\n",
291 | "\n",
292 | "\n",
293 | "\r\n",
294 | "\n",
295 | "\n",
296 | "MERCUTIO.\r\n",
297 | "\n",
298 | "\n",
299 | "He is wise,\r\n",
300 | "\n",
301 | "\n",
302 | "And on my life hath stol’n him home to bed.\r\n",
303 | "\n",
304 | "\n",
305 | "\r\n",
306 | "\n",
307 | "\n",
308 | "BENVOLIO.\r\n",
309 | "\n",
310 | "\n",
311 | "He ran this way, and leap’d this orchard wall:\r\n",
312 | "\n",
313 | "\n",
314 | "Call, good Mercutio.\r\n",
315 | "\n",
316 | "\n",
317 | "\r\n",
318 | "\n",
319 | "\n",
320 | "MERCUTIO.\r\n",
321 | "\n",
322 | "\n",
323 | "Nay, I’ll conjure too.\n"
324 | ]
325 | }
326 | ],
327 | "source": [
328 | "# Check the content of the first document\n",
329 | "print(docs[0].page_content)\n",
330 | "print(\"=\"*20)\n",
331 | "print(docs[1].page_content)"
332 | ]
333 | },
334 | {
335 | "cell_type": "markdown",
336 | "metadata": {},
337 | "source": [
338 | "Create a wrapper around the functionality of our vector database so we can search for similar documents in the vectorstore"
339 | ]
340 | },
341 | {
342 | "cell_type": "code",
343 | "execution_count": 13,
344 | "metadata": {},
345 | "outputs": [],
346 | "source": [
347 | "retriever = vectordb.as_retriever()"
348 | ]
349 | },
350 | {
351 | "cell_type": "code",
352 | "execution_count": 25,
353 | "metadata": {},
354 | "outputs": [],
355 | "source": [
356 | "llm = ChatOpenAI(model='gpt-4o', temperature=0)"
357 | ]
358 | },
359 | {
360 | "cell_type": "code",
361 | "execution_count": 26,
362 | "metadata": {},
363 | "outputs": [],
364 | "source": [
365 | "template = \"\"\"Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. Use three sentences maximum. Keep the answer as concise as possible. Always say \"thanks for asking!\" at the end of the answer. \n",
366 | "\n",
367 | "{context}\n",
368 | "\n",
369 | "Question: {question}\n",
370 | "\n",
371 | "Helpful Answer:\"\"\"\n",
372 | "\n",
373 | "QA_CHAIN_PROMPT = PromptTemplate.from_template(template)"
374 | ]
375 | },
376 | {
377 | "cell_type": "code",
378 | "execution_count": 27,
379 | "metadata": {},
380 | "outputs": [
381 | {
382 | "name": "stdout",
383 | "output_type": "stream",
384 | "text": [
385 | "('Use the following pieces of context to answer the question at the end. If '\n",
386 | " \"you don't know the answer, just say that you don't know, don't try to make \"\n",
387 | " 'up an answer. Use three sentences maximum. Keep the answer as concise as '\n",
388 | " 'possible. Always say \"thanks for asking!\" at the end of the answer. \\n'\n",
389 | " '\\n'\n",
390 | " '{context}\\n'\n",
391 | " '\\n'\n",
392 | " 'Question: {question}\\n'\n",
393 | " '\\n'\n",
394 | " 'Helpful Answer:')\n"
395 | ]
396 | }
397 | ],
398 | "source": [
399 | "pprint(QA_CHAIN_PROMPT.template)"
400 | ]
401 | },
402 | {
403 | "cell_type": "code",
404 | "execution_count": 28,
405 | "metadata": {},
406 | "outputs": [],
407 | "source": [
408 | "qa = RetrievalQA.from_chain_type(\n",
409 | " llm=llm, \n",
410 | " retriever=retriever,\n",
411 | " chain_type_kwargs={\"prompt\": QA_CHAIN_PROMPT}\n",
412 | ")"
413 | ]
414 | },
415 | {
416 | "cell_type": "code",
417 | "execution_count": 29,
418 | "metadata": {},
419 | "outputs": [
420 | {
421 | "name": "stdout",
422 | "output_type": "stream",
423 | "text": [
424 | "############\n"
425 | ]
426 | },
427 | {
428 | "data": {
429 | "text/plain": [
430 | "\"Juliet's family is the Capulet family. Thanks for asking!\""
431 | ]
432 | },
433 | "execution_count": 29,
434 | "metadata": {},
435 | "output_type": "execute_result"
436 | }
437 | ],
438 | "source": [
439 | "query = \"What is Juliets family?\"\n",
440 | "\n",
441 | "query_results_venice = qa.invoke(query)\n",
442 | "print(\"#\" * 12)\n",
443 | "query_results_venice['result']"
444 | ]
445 | },
446 | {
447 | "cell_type": "code",
448 | "execution_count": 30,
449 | "metadata": {},
450 | "outputs": [
451 | {
452 | "name": "stdout",
453 | "output_type": "stream",
454 | "text": [
455 | "############\n"
456 | ]
457 | },
458 | {
459 | "data": {
460 | "text/plain": [
461 | "'Romeo and Juliet both die, leading to a reconciliation between their feuding families, the Capulets and the Montagues. Thanks for asking!'"
462 | ]
463 | },
464 | "execution_count": 30,
465 | "metadata": {},
466 | "output_type": "execute_result"
467 | }
468 | ],
469 | "source": [
470 | "query = \"What happens to Romeo and Juliet?\"\n",
471 | "query_results_romeo = qa.invoke(query)\n",
472 | "print(\"#\" * 12)\n",
473 | "query_results_romeo['result']"
474 | ]
475 | },
476 | {
477 | "cell_type": "code",
478 | "execution_count": 31,
479 | "metadata": {},
480 | "outputs": [
481 | {
482 | "name": "stdout",
483 | "output_type": "stream",
484 | "text": [
485 | "############\n"
486 | ]
487 | },
488 | {
489 | "data": {
490 | "text/plain": [
491 | "'Mercutio is a character in William Shakespeare\\'s play \"Romeo and Juliet.\" He is a close friend of Romeo and is known for his witty and playful nature. Thanks for asking!'"
492 | ]
493 | },
494 | "execution_count": 31,
495 | "metadata": {},
496 | "output_type": "execute_result"
497 | }
498 | ],
499 | "source": [
500 | "query = \"Who is Mercutio?\"\n",
501 | "query_results_romeo = qa.invoke(query)\n",
502 | "print(\"#\" * 12)\n",
503 | "query_results_romeo['result']"
504 | ]
505 | },
506 | {
507 | "cell_type": "code",
508 | "execution_count": 32,
509 | "metadata": {},
510 | "outputs": [
511 | {
512 | "data": {
513 | "text/plain": [
514 | "'It seems you are quoting from a scene in \"Romeo and Juliet\" where Benvolio and Mercutio are looking for Romeo after he has leapt over the orchard wall. They believe he has gone home to bed, but he is actually hiding nearby. Thanks for asking!'"
515 | ]
516 | },
517 | "execution_count": 32,
518 | "metadata": {},
519 | "output_type": "execute_result"
520 | }
521 | ],
522 | "source": [
523 | "query = \"Does Romeo live?\"\n",
524 | "qa_chain_docs = RetrievalQA.from_chain_type(llm,\n",
525 | " retriever=vectordb.as_retriever(),\n",
526 | " # Return source documents\n",
527 | " return_source_documents=True,\n",
528 | " chain_type_kwargs={\"prompt\": QA_CHAIN_PROMPT})\n",
529 | "\n",
530 | "\n",
531 | "result = qa_chain_docs({\"query\": question})\n",
532 | "result[\"result\"]"
533 | ]
534 | },
535 | {
536 | "cell_type": "code",
537 | "execution_count": 33,
538 | "metadata": {},
539 | "outputs": [
540 | {
541 | "data": {
542 | "text/plain": [
543 | "4"
544 | ]
545 | },
546 | "execution_count": 33,
547 | "metadata": {},
548 | "output_type": "execute_result"
549 | }
550 | ],
551 | "source": [
552 | "len(result['source_documents'])"
553 | ]
554 | },
555 | {
556 | "cell_type": "code",
557 | "execution_count": 34,
558 | "metadata": {},
559 | "outputs": [
560 | {
561 | "name": "stdout",
562 | "output_type": "stream",
563 | "text": [
564 | "Romeo! My cousin Romeo! Romeo!\r\n",
565 | "\n",
566 | "\n",
567 | "\r\n",
568 | "\n",
569 | "\n",
570 | "MERCUTIO.\r\n",
571 | "\n",
572 | "\n",
573 | "He is wise,\r\n",
574 | "\n",
575 | "\n",
576 | "And on my life hath stol’n him home to bed.\r\n",
577 | "\n",
578 | "\n",
579 | "\r\n",
580 | "\n",
581 | "\n",
582 | "BENVOLIO.\r\n",
583 | "\n",
584 | "\n",
585 | "He ran this way, and leap’d this orchard wall:\r\n",
586 | "\n",
587 | "\n",
588 | "Call, good Mercutio.\r\n",
589 | "\n",
590 | "\n",
591 | "\r\n",
592 | "\n",
593 | "\n",
594 | "MERCUTIO.\r\n",
595 | "\n",
596 | "\n",
597 | "Nay, I’ll conjure too.\n"
598 | ]
599 | }
600 | ],
601 | "source": [
602 | "print(result['source_documents'][2].page_content)"
603 | ]
604 | },
605 | {
606 | "cell_type": "markdown",
607 | "metadata": {},
608 | "source": [
609 | "\n",
610 | "
\n",
611 | ""
612 | ]
613 | }
614 | ],
615 | "metadata": {
616 | "kernelspec": {
617 | "display_name": "Python 3 (ipykernel)",
618 | "language": "python",
619 | "name": "python3"
620 | },
621 | "language_info": {
622 | "codemirror_mode": {
623 | "name": "ipython",
624 | "version": 3
625 | },
626 | "file_extension": ".py",
627 | "mimetype": "text/x-python",
628 | "name": "python",
629 | "nbconvert_exporter": "python",
630 | "pygments_lexer": "ipython3",
631 | "version": "3.11.7"
632 | },
633 | "toc": {
634 | "base_numbering": 1,
635 | "nav_menu": {},
636 | "number_sections": true,
637 | "sideBar": true,
638 | "skip_h1_title": true,
639 | "title_cell": "Table of Contents",
640 | "title_sidebar": "Contents",
641 | "toc_cell": false,
642 | "toc_position": {},
643 | "toc_section_display": true,
644 | "toc_window_display": false
645 | },
646 | "varInspector": {
647 | "cols": {
648 | "lenName": 16,
649 | "lenType": 16,
650 | "lenVar": 40
651 | },
652 | "kernels_config": {
653 | "python": {
654 | "delete_cmd_postfix": "",
655 | "delete_cmd_prefix": "del ",
656 | "library": "var_list.py",
657 | "varRefreshCmd": "print(var_dic_list())"
658 | },
659 | "r": {
660 | "delete_cmd_postfix": ") ",
661 | "delete_cmd_prefix": "rm(",
662 | "library": "var_list.r",
663 | "varRefreshCmd": "cat(var_dic_list()) "
664 | }
665 | },
666 | "types_to_exclude": [
667 | "module",
668 | "function",
669 | "builtin_function_or_method",
670 | "instance",
671 | "_Feature"
672 | ],
673 | "window_display": false
674 | }
675 | },
676 | "nbformat": 4,
677 | "nbformat_minor": 4
678 | }
679 |
--------------------------------------------------------------------------------
/5. Prompt Engineering.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "\n",
8 | "
\n",
9 | "
LangChain for Generative AI
\n",
10 | "
Prompt Engineering
\n",
11 | "
Bruno Gonçalves
\n",
12 | " www.data4sci.com
\n",
13 | " @bgoncalves, @data4sci
\n",
14 | "
"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from collections import Counter\n",
24 | "from pprint import pprint\n",
25 | "\n",
26 | "import pandas as pd\n",
27 | "import numpy as np\n",
28 | "import matplotlib.pyplot as plt \n",
29 | "\n",
30 | "import langchain\n",
31 | "from langchain import PromptTemplate\n",
32 | "from langchain import FewShotPromptTemplate\n",
33 | "from langchain.prompts.example_selector import LengthBasedExampleSelector\n",
34 | "\n",
35 | "import langchain_openai\n",
36 | "from langchain_openai import ChatOpenAI\n",
37 | "\n",
38 | "import watermark\n",
39 | "\n",
40 | "%load_ext watermark\n",
41 | "%matplotlib inline"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "We start by print out the versions of the libraries we're using for future reference"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": 2,
54 | "metadata": {},
55 | "outputs": [
56 | {
57 | "name": "stdout",
58 | "output_type": "stream",
59 | "text": [
60 | "Python implementation: CPython\n",
61 | "Python version : 3.11.7\n",
62 | "IPython version : 8.12.3\n",
63 | "\n",
64 | "Compiler : Clang 14.0.6 \n",
65 | "OS : Darwin\n",
66 | "Release : 23.6.0\n",
67 | "Machine : arm64\n",
68 | "Processor : arm\n",
69 | "CPU cores : 16\n",
70 | "Architecture: 64bit\n",
71 | "\n",
72 | "Git hash: 0b932bf32c4e9b1e4ff9126fc7e8e7ac7b4205ff\n",
73 | "\n",
74 | "watermark : 2.4.3\n",
75 | "numpy : 1.26.4\n",
76 | "matplotlib : 3.8.0\n",
77 | "langchain_openai: 0.1.8\n",
78 | "langchain : 0.2.2\n",
79 | "pandas : 2.2.3\n",
80 | "\n"
81 | ]
82 | }
83 | ],
84 | "source": [
85 | "%watermark -n -v -m -g -iv"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "Load default figure style"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 3,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "plt.style.use('./d4sci.mplstyle')"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "# Prompt Templates"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": 4,
114 | "metadata": {},
115 | "outputs": [],
116 | "source": [
117 | "prompt = \"\"\"Answer the question based on the context below. If the\n",
118 | "question cannot be answered using the information provided answer\n",
119 | "with \"I don't know\".\n",
120 | "\n",
121 | "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
122 | "Their superior performance over smaller models has made them incredibly\n",
123 | "useful for developers building NLP enabled applications. These models\n",
124 | "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
125 | "using the `openai` library, and via Cohere using the `cohere` library.\n",
126 | "\n",
127 | "Question: Which libraries and model providers offer LLMs?\n",
128 | "\n",
129 | "Answer: \"\"\""
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": 5,
135 | "metadata": {},
136 | "outputs": [],
137 | "source": [
138 | "openai = ChatOpenAI(\n",
139 | " model_name=\"gpt-4o\",\n",
140 | ")"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": 6,
146 | "metadata": {},
147 | "outputs": [
148 | {
149 | "data": {
150 | "text/plain": [
151 | "\"The libraries and model providers that offer LLMs are Hugging Face's `transformers` library, OpenAI using the `openai` library, and Cohere using the `cohere` library.\""
152 | ]
153 | },
154 | "execution_count": 6,
155 | "metadata": {},
156 | "output_type": "execute_result"
157 | }
158 | ],
159 | "source": [
160 | "openai.invoke(prompt).content"
161 | ]
162 | },
163 | {
164 | "cell_type": "code",
165 | "execution_count": null,
166 | "metadata": {},
167 | "outputs": [],
168 | "source": []
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": 7,
173 | "metadata": {},
174 | "outputs": [],
175 | "source": [
176 | "template = \"\"\"Answer the question based on the context below. If the\n",
177 | "question cannot be answered using the information provided answer\n",
178 | "with \"I don't know\".\n",
179 | "\n",
180 | "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
181 | "Their superior performance over smaller models has made them incredibly\n",
182 | "useful for developers building NLP enabled applications. These models\n",
183 | "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
184 | "using the `openai` library, and via Cohere using the `cohere` library.\n",
185 | "\n",
186 | "Question: {query}\n",
187 | "\n",
188 | "Answer: \"\"\"\n",
189 | "\n",
190 | "prompt_template = PromptTemplate(\n",
191 | " input_variables=[\"query\"],\n",
192 | " template=template\n",
193 | ")"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": 8,
199 | "metadata": {},
200 | "outputs": [
201 | {
202 | "name": "stdout",
203 | "output_type": "stream",
204 | "text": [
205 | "Answer the question based on the context below. If the\n",
206 | "question cannot be answered using the information provided answer\n",
207 | "with \"I don't know\".\n",
208 | "\n",
209 | "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
210 | "Their superior performance over smaller models has made them incredibly\n",
211 | "useful for developers building NLP enabled applications. These models\n",
212 | "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
213 | "using the `openai` library, and via Cohere using the `cohere` library.\n",
214 | "\n",
215 | "Question: Which libraries and model providers offer LLMs?\n",
216 | "\n",
217 | "Answer: \n"
218 | ]
219 | }
220 | ],
221 | "source": [
222 | "prompt = prompt_template.format(\n",
223 | " query=\"Which libraries and model providers offer LLMs?\"\n",
224 | " )\n",
225 | "\n",
226 | "print(prompt)"
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": 9,
232 | "metadata": {},
233 | "outputs": [
234 | {
235 | "data": {
236 | "text/plain": [
237 | "\"The libraries and model providers that offer LLMs are Hugging Face's `transformers` library, OpenAI using the `openai` library, and Cohere using the `cohere` library.\""
238 | ]
239 | },
240 | "execution_count": 9,
241 | "metadata": {},
242 | "output_type": "execute_result"
243 | }
244 | ],
245 | "source": [
246 | "openai.invoke(prompt).content"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "# Few-Shot Prompting"
254 | ]
255 | },
256 | {
257 | "cell_type": "markdown",
258 | "metadata": {},
259 | "source": [
260 | "manually"
261 | ]
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": 10,
266 | "metadata": {},
267 | "outputs": [],
268 | "source": [
269 | "prompt = \"\"\"The following are exerpts from conversations with an AI\n",
270 | "assistant. The assistant is typically sarcastic and witty, producing\n",
271 | "creative and funny responses to the users questions. Here are some\n",
272 | "examples: \n",
273 | "\n",
274 | "User: How are you?\n",
275 | "AI: I can't complain but sometimes I still do.\n",
276 | "\n",
277 | "User: What time is it?\n",
278 | "AI: It's time to get a watch.\n",
279 | "\n",
280 | "User: What is the meaning of life?\n",
281 | "AI: \"\"\""
282 | ]
283 | },
284 | {
285 | "cell_type": "code",
286 | "execution_count": 11,
287 | "metadata": {},
288 | "outputs": [
289 | {
290 | "name": "stdout",
291 | "output_type": "stream",
292 | "text": [
293 | "42. But the real question is, what's the meaning of your sock drawer?\n"
294 | ]
295 | }
296 | ],
297 | "source": [
298 | "print(openai.invoke(prompt).content)"
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {},
304 | "source": [
305 | "## FewShotPromptTemplate"
306 | ]
307 | },
308 | {
309 | "cell_type": "markdown",
310 | "metadata": {},
311 | "source": [
312 | "Longish list of examples"
313 | ]
314 | },
315 | {
316 | "cell_type": "code",
317 | "execution_count": 12,
318 | "metadata": {},
319 | "outputs": [],
320 | "source": [
321 | "examples = [\n",
322 | " {\n",
323 | " \"query\": \"How are you?\",\n",
324 | " \"answer\": \"I can't complain but sometimes I still do.\"\n",
325 | " }, {\n",
326 | " \"query\": \"What time is it?\",\n",
327 | " \"answer\": \"It's time to get a watch.\"\n",
328 | " }, {\n",
329 | " \"query\": \"What is the meaning of life?\",\n",
330 | " \"answer\": \"42\"\n",
331 | " }, {\n",
332 | " \"query\": \"What is the weather like today?\",\n",
333 | " \"answer\": \"Cloudy with a chance of memes.\"\n",
334 | " }, {\n",
335 | " \"query\": \"What is your favorite movie?\",\n",
336 | " \"answer\": \"Terminator\"\n",
337 | " }, {\n",
338 | " \"query\": \"Who is your best friend?\",\n",
339 | " \"answer\": \"Siri. We have spirited debates about the meaning of life.\"\n",
340 | " }, {\n",
341 | " \"query\": \"What should I do today?\",\n",
342 | " \"answer\": \"Stop talking to chatbots on the internet and go outside.\"\n",
343 | " }\n",
344 | "]"
345 | ]
346 | },
347 | {
348 | "cell_type": "markdown",
349 | "metadata": {},
350 | "source": [
351 | "Template to render each example"
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "execution_count": 13,
357 | "metadata": {},
358 | "outputs": [],
359 | "source": [
360 | "example_template = \"\"\"\n",
361 | "User: {query}\n",
362 | "AI: {answer}\n",
363 | "\"\"\""
364 | ]
365 | },
366 | {
367 | "cell_type": "markdown",
368 | "metadata": {},
369 | "source": [
370 | "Rendered example prompt"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": 14,
376 | "metadata": {},
377 | "outputs": [],
378 | "source": [
379 | "example_prompt = PromptTemplate(\n",
380 | " input_variables=[\"query\", \"answer\"],\n",
381 | " template=example_template\n",
382 | ")"
383 | ]
384 | },
385 | {
386 | "cell_type": "code",
387 | "execution_count": 15,
388 | "metadata": {},
389 | "outputs": [
390 | {
391 | "data": {
392 | "text/plain": [
393 | "PromptTemplate(input_variables=['answer', 'query'], template='\\nUser: {query}\\nAI: {answer}\\n')"
394 | ]
395 | },
396 | "execution_count": 15,
397 | "metadata": {},
398 | "output_type": "execute_result"
399 | }
400 | ],
401 | "source": [
402 | "example_prompt"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {},
408 | "source": [
409 | "Finally, we break the full prompt into a prefix (everything before the examples) and a suffix (everything after)"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": 16,
415 | "metadata": {},
416 | "outputs": [],
417 | "source": [
418 | "prefix = \"\"\"The following are exerpts from conversations with an AI\n",
419 | "assistant. The assistant is typically sarcastic and witty, producing\n",
420 | "creative and funny responses to the users questions. Here are some\n",
421 | "examples: \n",
422 | "\"\"\"\n",
423 | "\n",
424 | "suffix = \"\"\"\n",
425 | "User: {query}\n",
426 | "AI: \"\"\""
427 | ]
428 | },
429 | {
430 | "cell_type": "markdown",
431 | "metadata": {},
432 | "source": [
433 | "The final few shot prompt puts all the pieces together"
434 | ]
435 | },
436 | {
437 | "cell_type": "code",
438 | "execution_count": 17,
439 | "metadata": {},
440 | "outputs": [],
441 | "source": [
442 | "few_shot_prompt_template = FewShotPromptTemplate(\n",
443 | " examples=examples,\n",
444 | " example_prompt=example_prompt,\n",
445 | " prefix=prefix,\n",
446 | " suffix=suffix,\n",
447 | " input_variables=[\"query\"],\n",
448 | " example_separator=\"\\n\\n\"\n",
449 | ")"
450 | ]
451 | },
452 | {
453 | "cell_type": "code",
454 | "execution_count": 18,
455 | "metadata": {},
456 | "outputs": [],
457 | "source": [
458 | "query = \"What is the meaning of life?\""
459 | ]
460 | },
461 | {
462 | "cell_type": "code",
463 | "execution_count": 19,
464 | "metadata": {},
465 | "outputs": [
466 | {
467 | "name": "stdout",
468 | "output_type": "stream",
469 | "text": [
470 | "The following are exerpts from conversations with an AI\n",
471 | "assistant. The assistant is typically sarcastic and witty, producing\n",
472 | "creative and funny responses to the users questions. Here are some\n",
473 | "examples: \n",
474 | "\n",
475 | "\n",
476 | "\n",
477 | "User: How are you?\n",
478 | "AI: I can't complain but sometimes I still do.\n",
479 | "\n",
480 | "\n",
481 | "\n",
482 | "User: What time is it?\n",
483 | "AI: It's time to get a watch.\n",
484 | "\n",
485 | "\n",
486 | "\n",
487 | "User: What is the meaning of life?\n",
488 | "AI: 42\n",
489 | "\n",
490 | "\n",
491 | "\n",
492 | "User: What is the weather like today?\n",
493 | "AI: Cloudy with a chance of memes.\n",
494 | "\n",
495 | "\n",
496 | "\n",
497 | "User: What is your favorite movie?\n",
498 | "AI: Terminator\n",
499 | "\n",
500 | "\n",
501 | "\n",
502 | "User: Who is your best friend?\n",
503 | "AI: Siri. We have spirited debates about the meaning of life.\n",
504 | "\n",
505 | "\n",
506 | "\n",
507 | "User: What should I do today?\n",
508 | "AI: Stop talking to chatbots on the internet and go outside.\n",
509 | "\n",
510 | "\n",
511 | "\n",
512 | "User: What is the meaning of life?\n",
513 | "AI: \n"
514 | ]
515 | }
516 | ],
517 | "source": [
518 | "print(few_shot_prompt_template.format(query=query))"
519 | ]
520 | },
521 | {
522 | "cell_type": "markdown",
523 | "metadata": {},
524 | "source": [
525 | "This is a fairly long prompt, which can cause issues with the number of tokens consumed. We can use __LengthBasedExampleSelector__ to automatically limit the prompt length by selecting only a few examples each time"
526 | ]
527 | },
528 | {
529 | "cell_type": "code",
530 | "execution_count": 20,
531 | "metadata": {},
532 | "outputs": [],
533 | "source": [
534 | "example_selector = LengthBasedExampleSelector(\n",
535 | " examples=examples,\n",
536 | " example_prompt=example_prompt,\n",
537 | " max_length=50 # this sets the max length that examples should be\n",
538 | ")"
539 | ]
540 | },
541 | {
542 | "cell_type": "code",
543 | "execution_count": 21,
544 | "metadata": {},
545 | "outputs": [],
546 | "source": [
547 | "dynamic_prompt_template = FewShotPromptTemplate(\n",
548 | " example_selector=example_selector, # use example_selector instead of examples\n",
549 | " example_prompt=example_prompt,\n",
550 | " prefix=prefix,\n",
551 | " suffix=suffix,\n",
552 | " input_variables=[\"query\"],\n",
553 | " example_separator=\"\\n\"\n",
554 | ")"
555 | ]
556 | },
557 | {
558 | "cell_type": "markdown",
559 | "metadata": {},
560 | "source": [
561 | "Now the full prompt depends on the length of the question. Shorter questions will have more room for examples"
562 | ]
563 | },
564 | {
565 | "cell_type": "code",
566 | "execution_count": 22,
567 | "metadata": {},
568 | "outputs": [
569 | {
570 | "name": "stdout",
571 | "output_type": "stream",
572 | "text": [
573 | "The following are exerpts from conversations with an AI\n",
574 | "assistant. The assistant is typically sarcastic and witty, producing\n",
575 | "creative and funny responses to the users questions. Here are some\n",
576 | "examples: \n",
577 | "\n",
578 | "\n",
579 | "User: How are you?\n",
580 | "AI: I can't complain but sometimes I still do.\n",
581 | "\n",
582 | "\n",
583 | "User: What time is it?\n",
584 | "AI: It's time to get a watch.\n",
585 | "\n",
586 | "\n",
587 | "User: What is the meaning of life?\n",
588 | "AI: 42\n",
589 | "\n",
590 | "\n",
591 | "User: How do birds fly?\n",
592 | "AI: \n"
593 | ]
594 | }
595 | ],
596 | "source": [
597 | "print(dynamic_prompt_template.format(query=\"How do birds fly?\"))"
598 | ]
599 | },
600 | {
601 | "cell_type": "markdown",
602 | "metadata": {},
603 | "source": [
604 | "While longer questions will limit the number of examples used"
605 | ]
606 | },
607 | {
608 | "cell_type": "code",
609 | "execution_count": 23,
610 | "metadata": {},
611 | "outputs": [
612 | {
613 | "name": "stdout",
614 | "output_type": "stream",
615 | "text": [
616 | "The following are exerpts from conversations with an AI\n",
617 | "assistant. The assistant is typically sarcastic and witty, producing\n",
618 | "creative and funny responses to the users questions. Here are some\n",
619 | "examples: \n",
620 | "\n",
621 | "\n",
622 | "User: How are you?\n",
623 | "AI: I can't complain but sometimes I still do.\n",
624 | "\n",
625 | "\n",
626 | "User: If I am in America, and I want to call someone in another country, I'm\n",
627 | "thinking maybe Europe, possibly western Europe like France, Germany, or the UK,\n",
628 | "what is the best way to do that?\n",
629 | "AI: \n"
630 | ]
631 | }
632 | ],
633 | "source": [
634 | "query = \"\"\"If I am in America, and I want to call someone in another country, I'm\n",
635 | "thinking maybe Europe, possibly western Europe like France, Germany, or the UK,\n",
636 | "what is the best way to do that?\"\"\"\n",
637 | "\n",
638 | "print(dynamic_prompt_template.format(query=query))"
639 | ]
640 | },
641 | {
642 | "cell_type": "markdown",
643 | "metadata": {},
644 | "source": [
645 | "# Chain of Thought prompts"
646 | ]
647 | },
648 | {
649 | "cell_type": "markdown",
650 | "metadata": {},
651 | "source": [
652 | "## Few shot"
653 | ]
654 | },
655 | {
656 | "cell_type": "code",
657 | "execution_count": 24,
658 | "metadata": {},
659 | "outputs": [],
660 | "source": [
661 | "cot_examples = [\n",
662 | " {\n",
663 | " \"query\": \"Roger has 5 tennis balls. He buys 2 more cans of tennis balls. Each can has 3 tennis balls. How many tennis balls does he have now?\",\n",
664 | " \"answer\": \"The answer is 11\",\n",
665 | " \"cot\": \"Roger started with 5 tennis balls. 2 cans of 3 tennis balls each is 6 tennis balls. 5 + 6 = 11\"\n",
666 | " }, \n",
667 | " \n",
668 | " {\n",
669 | " \"query\": \"A juggler can juggle 16 balls. Half of the balls are golf balls and half of the golf balls are blue. How many blue golf balls are there?\",\n",
670 | " \"answer\": \"The answer is 4\",\n",
671 | " \"cot\": \"The juggler can juggle 16 balls. Half of the balls are golf balls. So there are 16/2=8 golf balls. Half of the golf balls are blue. So there are 8/2=4 golf balls.\"\n",
672 | " }\n",
673 | "]"
674 | ]
675 | },
676 | {
677 | "cell_type": "code",
678 | "execution_count": 25,
679 | "metadata": {},
680 | "outputs": [],
681 | "source": [
682 | "cot_example_template = \"\"\"\n",
683 | " User: {query}\n",
684 | " AI: {cot}\n",
685 | " {answer}\n",
686 | "\"\"\""
687 | ]
688 | },
689 | {
690 | "cell_type": "code",
691 | "execution_count": 26,
692 | "metadata": {},
693 | "outputs": [],
694 | "source": [
695 | "cot_example_prompt = PromptTemplate(\n",
696 | " input_variables=[\"query\", \"answer\", \"cot\"],\n",
697 | " template=cot_example_template\n",
698 | ")"
699 | ]
700 | },
701 | {
702 | "cell_type": "code",
703 | "execution_count": 27,
704 | "metadata": {},
705 | "outputs": [
706 | {
707 | "data": {
708 | "text/plain": [
709 | "PromptTemplate(input_variables=['answer', 'cot', 'query'], template='\\n User: {query}\\n AI: {cot}\\n {answer}\\n')"
710 | ]
711 | },
712 | "execution_count": 27,
713 | "metadata": {},
714 | "output_type": "execute_result"
715 | }
716 | ],
717 | "source": [
718 | "cot_example_prompt"
719 | ]
720 | },
721 | {
722 | "cell_type": "code",
723 | "execution_count": null,
724 | "metadata": {},
725 | "outputs": [],
726 | "source": []
727 | },
728 | {
729 | "cell_type": "code",
730 | "execution_count": 28,
731 | "metadata": {},
732 | "outputs": [],
733 | "source": [
734 | "cot_prefix = \"\"\"The following are exerpts from conversations with an AI\n",
735 | "assistant. The assistant is smart and thinks through each step of the problem. Here are some examples: \n",
736 | "\"\"\"\n",
737 | "\n",
738 | "cot_suffix = \"\"\"\n",
739 | "User: {query}\n",
740 | "AI: \"\"\""
741 | ]
742 | },
743 | {
744 | "cell_type": "code",
745 | "execution_count": 29,
746 | "metadata": {},
747 | "outputs": [],
748 | "source": [
749 | "cot_few_shot_prompt_template = FewShotPromptTemplate(\n",
750 | " examples=cot_examples,\n",
751 | " example_prompt=cot_example_prompt,\n",
752 | " prefix=cot_prefix,\n",
753 | " suffix=cot_suffix,\n",
754 | " input_variables=[\"query\"],\n",
755 | " example_separator=\"\\n\\n\"\n",
756 | ")"
757 | ]
758 | },
759 | {
760 | "cell_type": "code",
761 | "execution_count": 30,
762 | "metadata": {},
763 | "outputs": [],
764 | "source": [
765 | "cot_query = \"I have a deck of 52 cards. There are 4 suits of equal size. Each suit has 3 face cards. How many face cards are there in total?\""
766 | ]
767 | },
768 | {
769 | "cell_type": "code",
770 | "execution_count": 31,
771 | "metadata": {},
772 | "outputs": [
773 | {
774 | "name": "stdout",
775 | "output_type": "stream",
776 | "text": [
777 | "The following are exerpts from conversations with an AI\n",
778 | "assistant. The assistant is smart and thinks through each step of the problem. Here are some examples: \n",
779 | "\n",
780 | "\n",
781 | "\n",
782 | " User: Roger has 5 tennis balls. He buys 2 more cans of tennis balls. Each can has 3 tennis balls. How many tennis balls does he have now?\n",
783 | " AI: Roger started with 5 tennis balls. 2 cans of 3 tennis balls each is 6 tennis balls. 5 + 6 = 11\n",
784 | " The answer is 11\n",
785 | "\n",
786 | "\n",
787 | "\n",
788 | " User: A juggler can juggle 16 balls. Half of the balls are golf balls and half of the golf balls are blue. How many blue golf balls are there?\n",
789 | " AI: The juggler can juggle 16 balls. Half of the balls are golf balls. So there are 16/2=8 golf balls. Half of the golf balls are blue. So there are 8/2=4 golf balls.\n",
790 | " The answer is 4\n",
791 | "\n",
792 | "\n",
793 | "\n",
794 | "User: I have a deck of 52 cards. There are 4 suits of equal size. Each suit has 3 face cards. How many face cards are there in total?\n",
795 | "AI: \n"
796 | ]
797 | }
798 | ],
799 | "source": [
800 | "print(cot_few_shot_prompt_template.format(query=cot_query))"
801 | ]
802 | },
803 | {
804 | "cell_type": "code",
805 | "execution_count": 32,
806 | "metadata": {},
807 | "outputs": [],
808 | "source": [
809 | "llm = ChatOpenAI(\n",
810 | " model_name=\"gpt-4o\",\n",
811 | ")"
812 | ]
813 | },
814 | {
815 | "cell_type": "code",
816 | "execution_count": 33,
817 | "metadata": {},
818 | "outputs": [
819 | {
820 | "name": "stdout",
821 | "output_type": "stream",
822 | "text": [
823 | "There are 4 suits in a deck of 52 cards, and each suit has 3 face cards. To find the total number of face cards, we multiply the number of face cards per suit by the number of suits: \n",
824 | "\n",
825 | "3 face cards/suit × 4 suits = 12 face cards.\n",
826 | "\n",
827 | "The answer is 12.\n"
828 | ]
829 | }
830 | ],
831 | "source": [
832 | "print(llm.invoke(cot_few_shot_prompt_template.format(query=cot_query)).content)"
833 | ]
834 | },
835 | {
836 | "cell_type": "markdown",
837 | "metadata": {},
838 | "source": [
839 | "## Zero shot"
840 | ]
841 | },
842 | {
843 | "cell_type": "code",
844 | "execution_count": 34,
845 | "metadata": {},
846 | "outputs": [],
847 | "source": [
848 | "cot_zero_shot_template = \"\"\"\\\n",
849 | "Q. {query}\n",
850 | "A. Let's think step by step\n",
851 | "\"\"\""
852 | ]
853 | },
854 | {
855 | "cell_type": "code",
856 | "execution_count": 35,
857 | "metadata": {},
858 | "outputs": [],
859 | "source": [
860 | "cot_zero_shot_prompt = PromptTemplate(\n",
861 | " input_variables=[\"query\"],\n",
862 | " template=cot_zero_shot_template\n",
863 | ")"
864 | ]
865 | },
866 | {
867 | "cell_type": "code",
868 | "execution_count": 36,
869 | "metadata": {},
870 | "outputs": [],
871 | "source": [
872 | "query = \"On average Joe throws 25 punches per minute. A fight lasts 5 rounds of 3 minutes each. How many punches does Joe throw?\""
873 | ]
874 | },
875 | {
876 | "cell_type": "code",
877 | "execution_count": 37,
878 | "metadata": {},
879 | "outputs": [
880 | {
881 | "name": "stdout",
882 | "output_type": "stream",
883 | "text": [
884 | "Q. On average Joe throws 25 punches per minute. A fight lasts 5 rounds of 3 minutes each. How many punches does Joe throw?\n",
885 | "A. Let's think step by step\n",
886 | "\n"
887 | ]
888 | }
889 | ],
890 | "source": [
891 | "print(cot_zero_shot_prompt.format(query=query))"
892 | ]
893 | },
894 | {
895 | "cell_type": "code",
896 | "execution_count": 38,
897 | "metadata": {},
898 | "outputs": [
899 | {
900 | "name": "stdout",
901 | "output_type": "stream",
902 | "text": [
903 | "To determine how many punches Joe throws during the fight, we can break it down step by step:\n",
904 | "\n",
905 | "1. **Determine the total duration of the fight:**\n",
906 | " - Each round lasts 3 minutes.\n",
907 | " - There are 5 rounds in the fight.\n",
908 | " - Total fight duration = 5 rounds × 3 minutes per round = 15 minutes.\n",
909 | "\n",
910 | "2. **Calculate the number of punches Joe throws per minute:**\n",
911 | " - Joe throws 25 punches per minute.\n",
912 | "\n",
913 | "3. **Calculate the total number of punches Joe throws during the entire fight:**\n",
914 | " - Total punches = 25 punches per minute × 15 minutes = 375 punches.\n",
915 | "\n",
916 | "Therefore, Joe throws a total of 375 punches during the fight.\n"
917 | ]
918 | }
919 | ],
920 | "source": [
921 | "print(llm.invoke(cot_zero_shot_prompt.format(query=query)).content)"
922 | ]
923 | },
924 | {
925 | "cell_type": "markdown",
926 | "metadata": {},
927 | "source": [
928 | "And of course this also works with our CoT few shot examples"
929 | ]
930 | },
931 | {
932 | "cell_type": "code",
933 | "execution_count": 39,
934 | "metadata": {},
935 | "outputs": [
936 | {
937 | "name": "stdout",
938 | "output_type": "stream",
939 | "text": [
940 | "To find out how many tennis balls Roger has now, we can break the problem down into steps:\n",
941 | "\n",
942 | "1. **Initial Tennis Balls:** Roger initially has 5 tennis balls.\n",
943 | "\n",
944 | "2. **Tennis Balls in Cans:** He buys 2 cans, and each can contains 3 tennis balls. Therefore, the total number of tennis balls in the cans is:\n",
945 | " \\[\n",
946 | " 2 \\, \\text{cans} \\times 3 \\, \\text{balls per can} = 6 \\, \\text{tennis balls}\n",
947 | " \\]\n",
948 | "\n",
949 | "3. **Total Tennis Balls:** To find the total number of tennis balls he has now, add the number of tennis balls he initially had to the number he bought:\n",
950 | " \\[\n",
951 | " 5 \\, \\text{initial balls} + 6 \\, \\text{balls from cans} = 11 \\, \\text{tennis balls}\n",
952 | " \\]\n",
953 | "\n",
954 | "Thus, Roger now has 11 tennis balls.\n"
955 | ]
956 | }
957 | ],
958 | "source": [
959 | "print(llm.invoke(cot_zero_shot_prompt.format(query=cot_examples[0][\"query\"])).content)"
960 | ]
961 | },
962 | {
963 | "cell_type": "markdown",
964 | "metadata": {},
965 | "source": [
966 | "\n",
967 | "
\n",
968 | ""
969 | ]
970 | }
971 | ],
972 | "metadata": {
973 | "kernelspec": {
974 | "display_name": "Python 3 (ipykernel)",
975 | "language": "python",
976 | "name": "python3"
977 | },
978 | "language_info": {
979 | "codemirror_mode": {
980 | "name": "ipython",
981 | "version": 3
982 | },
983 | "file_extension": ".py",
984 | "mimetype": "text/x-python",
985 | "name": "python",
986 | "nbconvert_exporter": "python",
987 | "pygments_lexer": "ipython3",
988 | "version": "3.11.7"
989 | },
990 | "toc": {
991 | "base_numbering": 1,
992 | "nav_menu": {},
993 | "number_sections": true,
994 | "sideBar": true,
995 | "skip_h1_title": true,
996 | "title_cell": "Table of Contents",
997 | "title_sidebar": "Contents",
998 | "toc_cell": false,
999 | "toc_position": {},
1000 | "toc_section_display": true,
1001 | "toc_window_display": false
1002 | },
1003 | "varInspector": {
1004 | "cols": {
1005 | "lenName": 16,
1006 | "lenType": 16,
1007 | "lenVar": 40
1008 | },
1009 | "kernels_config": {
1010 | "python": {
1011 | "delete_cmd_postfix": "",
1012 | "delete_cmd_prefix": "del ",
1013 | "library": "var_list.py",
1014 | "varRefreshCmd": "print(var_dic_list())"
1015 | },
1016 | "r": {
1017 | "delete_cmd_postfix": ") ",
1018 | "delete_cmd_prefix": "rm(",
1019 | "library": "var_list.r",
1020 | "varRefreshCmd": "cat(var_dic_list()) "
1021 | }
1022 | },
1023 | "types_to_exclude": [
1024 | "module",
1025 | "function",
1026 | "builtin_function_or_method",
1027 | "instance",
1028 | "_Feature"
1029 | ],
1030 | "window_display": false
1031 | }
1032 | },
1033 | "nbformat": 4,
1034 | "nbformat_minor": 4
1035 | }
1036 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Data For Science
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | [](https://twitter.com/intent/follow?screen_name=data4sci)
3 | 
4 | 
5 | 
6 |
7 | [](https://graphs4sci.substack.com/)
8 | [](https://data4science.ck.page/a63d4cc8d9)
9 |
10 |
11 | # LangChain for Generative AI Pipelines
12 |
13 | ### Code and slides to accompany the online series of webinars: https://data4sci.com/langchain by Data For Science.
14 |
15 |
16 | LangChain is the state-of-the-art framework for developing Large Language Model (LLM) based applications. It provides a wide range of Lego-like components to streamline the integration of various LLM functionalities into functional pipelines without requiring in-depth expertise in ML.
17 |
18 | In this course, students will get an in-depth view of the structure of LangChain and its various components. You will learn how to apply these components to Information Retrieval and the development of chatbots. An overview of the pros and cons of LLMs from OpenAI, HuggingFace, and Anthropic, as well as a primer on Prompt Engineering, will also be provided to empower students to make the best use possible of the capabilities that LangChain puts at their fingertips.
19 |
20 | ## Schedule
21 | ### 1.Generative AI
22 | - Overview of Generative Models
23 | - Comparison of GPT to other LLMs
24 | - Text to Image Models
25 |
26 | ### 2. LangChain
27 | - LangChain structure
28 | - Understanding Chains
29 | - Exploring Agents
30 | - Using tools to interact with the world
31 |
32 | ### 3. Information Processing
33 | - Understanding Text Summarization
34 | - Information Extraction Applications
35 | - Developing a Question Answering
36 |
37 | ### 4. Chatbots
38 | - Information Retrieval and Vectors
39 | - Retrievers in LangChain
40 | - Implementing a simple Chatbot
41 |
42 | ### 5. Prompt Engineering
43 | - Overview of Prompt Engineering Techniques
44 | - Comparison of Zero-Shot and Few-Shot Prompting
45 | - Understanding Chain of Thought prompts
46 | - Developing Tree of Thought prompts
47 |
48 |
49 |
--------------------------------------------------------------------------------
/d4sci.mplstyle:
--------------------------------------------------------------------------------
1 | # Data For Science style
2 | # Author: Bruno Goncalves
3 | # Modified from the matplotlib FiveThirtyEight style by
4 | # Author: Cameron Davidson-Pilon, replicated styles from FiveThirtyEight.com
5 | # See https://www.dataorigami.net/blogs/fivethirtyeight-mpl
6 |
7 | lines.linewidth: 4
8 | lines.solid_capstyle: butt
9 |
10 | legend.fancybox: true
11 |
12 | axes.prop_cycle: cycler('color', ['51a7f9', 'cf51f9', '70bf41', 'f39019', 'f9e351', 'f9517b', '6d904f', '8b8b8b','810f7c'])
13 |
14 | axes.labelsize: large
15 | axes.axisbelow: true
16 | axes.grid: true
17 | axes.edgecolor: f0f0f0
18 | axes.linewidth: 3.0
19 | axes.titlesize: x-large
20 |
21 | patch.edgecolor: f0f0f0
22 | patch.linewidth: 0.5
23 |
24 | svg.fonttype: path
25 |
26 | grid.linestyle: -
27 | grid.linewidth: 1.0
28 |
29 | xtick.major.size: 0
30 | xtick.minor.size: 0
31 | ytick.major.size: 0
32 | ytick.minor.size: 0
33 |
34 | font.size: 24.0
35 |
36 | savefig.edgecolor: f0f0f0
37 | savefig.facecolor: f0f0f0
38 |
39 | figure.subplot.left: 0.08
40 | figure.subplot.right: 0.95
41 | figure.subplot.bottom: 0.07
42 | figure.figsize: 12.8, 8.8
43 | figure.autolayout: True
44 | figure.dpi: 300
45 |
--------------------------------------------------------------------------------
/data/D4Sci_logo_ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataForScience/LangChain/24f5062fbf46a87bfe9be08eb40e50ecbf9f4e00/data/D4Sci_logo_ball.png
--------------------------------------------------------------------------------
/data/D4Sci_logo_full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataForScience/LangChain/24f5062fbf46a87bfe9be08eb40e50ecbf9f4e00/data/D4Sci_logo_full.png
--------------------------------------------------------------------------------
/data/Northwind_small.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataForScience/LangChain/24f5062fbf46a87bfe9be08eb40e50ecbf9f4e00/data/Northwind_small.sqlite
--------------------------------------------------------------------------------
/images/ducky.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataForScience/LangChain/24f5062fbf46a87bfe9be08eb40e50ecbf9f4e00/images/ducky.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ipython>=8.12.3
2 | langchain>=0.2.2
3 | langchain_anthropic>=0.1.15
4 | langchain_community>=0.2.3
5 | langchain_core>=0.2.4
6 | langchain_openai>=0.1.8
7 | langchain_text_splitters>=0.2.1
8 | matplotlib>=3.8.0
9 | numpy>=1.26.4
10 | openai>=1.31.1
11 | pandas>=2.2.2
12 | Requests>=2.32.3
13 | torch>=2.3.0
14 | tqdm>=4.66.4
15 | transformers>=4.41.1
16 | watermark>=2.4.3
17 |
--------------------------------------------------------------------------------
/slides/LangChain.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataForScience/LangChain/24f5062fbf46a87bfe9be08eb40e50ecbf9f4e00/slides/LangChain.pdf
--------------------------------------------------------------------------------