├── .gitignore
├── .env.example
├── README.md
├── Conversation_Streaming.ipynb
├── Langchain_Conversational_Chatbot_SummaryMemory.ipynb
├── Langchain_Conversational_Chatbot.ipynb
└── Langchain_Conversational_Chatbot_Memory_Types.ipynb
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | OPENAI_API_KEY=1234567890
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Langchain Conversational Chatbot
2 |
3 | This is an example showing you how to enable coherent conversation with OpenAI by the support of Langchain framework.
4 |
5 | The key components we are using are as follows:
6 | - ConversationChain
7 | - ConversationBufferMemory
8 | - ConversationSummaryMemory
9 | - ConversationBufferWindowMemory
10 | - ConversationSummaryBufferMemory
11 |
12 | There are 3 Python notebooks included in this repository.
13 |
14 | ## [Langchain_Conversational_Chatbot.ipynb](./Langchain_Conversational_Chatbot.ipynb)
15 |
16 | This is a simple example of ConversationBufferMemory usage.
17 | ## [Langchain_Conversational_Chatbot_SummaryMemory.ipynb](./Langchain_Conversational_Chatbot_SummaryMemory.ipynb)
18 |
19 | This is a simple example of ConversationSummaryMemory usage.
20 |
21 | ## [Langchain_Conversational_Chatbot_Memory_Types.ipynb](./Langchain_Conversational_Chatbot_Memory_Types.ipynb)
22 |
23 | In this notebook, we will run 10 queries with the 4 different types of memory components *ConversationBufferMemory*, *ConversationSummaryMemory*, *ConversationBufferWindowMemory* and *ConversationSummaryBufferMemory* respectively.
24 |
25 | Token usage per conversation will be collected in these 4 executions and plotted so that we can have a better understanding on how tokens are consumed differently.
26 |
27 | Hope it helps. Feel free to PR if you see any issue. Thanks.
--------------------------------------------------------------------------------
/Conversation_Streaming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 39,
16 | "metadata": {
17 | "id": "RdSvP1Oi7LCc"
18 | },
19 | "outputs": [
20 | {
21 | "name": "stderr",
22 | "output_type": "stream",
23 | "text": [
24 | "4338.22s - pydevd: Sending message related to process being replaced timed-out after 5 seconds\n"
25 | ]
26 | },
27 | {
28 | "name": "stdout",
29 | "output_type": "stream",
30 | "text": [
31 | "Requirement already satisfied: langchain==0.0.138 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (0.0.138)\n",
32 | "Requirement already satisfied: openapi-schema-pydantic<2.0,>=1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (1.2.4)\n",
33 | "Requirement already satisfied: PyYAML>=5.4.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (6.0)\n",
34 | "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (3.8.4)\n",
35 | "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (4.0.2)\n",
36 | "Requirement already satisfied: dataclasses-json<0.6.0,>=0.5.7 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (0.5.7)\n",
37 | "Requirement already satisfied: pydantic<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (1.10.7)\n",
38 | "Requirement already satisfied: requests<3,>=2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (2.28.2)\n",
39 | "Requirement already satisfied: numpy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (1.23.5)\n",
40 | "Requirement already satisfied: SQLAlchemy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (1.4.47)\n",
41 | "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain==0.0.138) (8.2.2)\n",
42 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (3.1.0)\n",
43 | "Requirement already satisfied: attrs>=17.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (22.2.0)\n",
44 | "Requirement already satisfied: aiosignal>=1.1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (1.3.1)\n",
45 | "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (1.8.2)\n",
46 | "Requirement already satisfied: frozenlist>=1.1.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (1.3.3)\n",
47 | "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.138) (6.0.4)\n",
48 | "Requirement already satisfied: marshmallow<4.0.0,>=3.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.138) (3.19.0)\n",
49 | "Requirement already satisfied: marshmallow-enum<2.0.0,>=1.5.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.138) (1.5.1)\n",
50 | "Requirement already satisfied: typing-inspect>=0.4.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.138) (0.8.0)\n",
51 | "Requirement already satisfied: typing-extensions>=4.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from pydantic<2,>=1->langchain==0.0.138) (4.5.0)\n",
52 | "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain==0.0.138) (1.26.15)\n",
53 | "Requirement already satisfied: certifi>=2017.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain==0.0.138) (2022.12.7)\n",
54 | "Requirement already satisfied: idna<4,>=2.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain==0.0.138) (3.4)\n",
55 | "Requirement already satisfied: greenlet!=0.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from SQLAlchemy<2,>=1->langchain==0.0.138) (2.0.2)\n",
56 | "Requirement already satisfied: packaging>=17.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.138) (23.0)\n",
57 | "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from typing-inspect>=0.4.0->dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.138) (1.0.0)\n",
58 | "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.\n",
59 | "You should consider upgrading via the '/Users/wyang14/.pyenv/versions/3.9.16/bin/python -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
60 | "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n"
61 | ]
62 | }
63 | ],
64 | "source": [
65 | "%pip install langchain==0.0.138"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": 45,
71 | "metadata": {
72 | "id": "CcSMVHBz6zrj"
73 | },
74 | "outputs": [],
75 | "source": [
76 | "from langchain import OpenAI\n",
77 | "from langchain.callbacks import get_openai_callback\n",
78 | "from langchain.callbacks.base import CallbackManager\n",
79 | "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n",
80 | "import os"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 46,
86 | "metadata": {
87 | "colab": {
88 | "base_uri": "https://localhost:8080/",
89 | "height": 373
90 | },
91 | "id": "akq_I-dn-hpd",
92 | "outputId": "317e220b-914e-45b8-e1a8-ee92c838ad77"
93 | },
94 | "outputs": [],
95 | "source": [
96 | "llm = OpenAI(\n",
97 | " temperature=0,\n",
98 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
99 | "\tmodel_name=\"text-davinci-003\",\n",
100 | " callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]),\n",
101 | " verbose=True,\n",
102 | " streaming=True\n",
103 | ")"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": 48,
109 | "metadata": {},
110 | "outputs": [],
111 | "source": [
112 | "response = llm(\"Please write an English poem with 50 lines and 10 syllables per line.\")"
113 | ]
114 | }
115 | ],
116 | "metadata": {
117 | "colab": {
118 | "authorship_tag": "ABX9TyMr1K4oquJDHksnEw+MRPeP",
119 | "include_colab_link": true,
120 | "provenance": []
121 | },
122 | "kernelspec": {
123 | "display_name": "Python 3",
124 | "name": "python3"
125 | },
126 | "language_info": {
127 | "codemirror_mode": {
128 | "name": "ipython",
129 | "version": 3
130 | },
131 | "file_extension": ".py",
132 | "mimetype": "text/x-python",
133 | "name": "python",
134 | "nbconvert_exporter": "python",
135 | "pygments_lexer": "ipython3",
136 | "version": "3.9.16"
137 | }
138 | },
139 | "nbformat": 4,
140 | "nbformat_minor": 0
141 | }
142 |
--------------------------------------------------------------------------------
/Langchain_Conversational_Chatbot_SummaryMemory.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 11,
16 | "metadata": {
17 | "id": "RdSvP1Oi7LCc"
18 | },
19 | "outputs": [
20 | {
21 | "name": "stdout",
22 | "output_type": "stream",
23 | "text": [
24 | "Requirement already satisfied: langchain in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (0.0.135)\n",
25 | "Requirement already satisfied: dataclasses-json<0.6.0,>=0.5.7 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (0.5.7)\n",
26 | "Requirement already satisfied: pydantic<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.10.7)\n",
27 | "Requirement already satisfied: SQLAlchemy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.4.47)\n",
28 | "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (8.2.2)\n",
29 | "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (3.8.4)\n",
30 | "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (4.0.2)\n",
31 | "Requirement already satisfied: PyYAML>=5.4.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (6.0)\n",
32 | "Requirement already satisfied: numpy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.23.5)\n",
33 | "Requirement already satisfied: openapi-schema-pydantic<2.0,>=1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.2.4)\n",
34 | "Requirement already satisfied: requests<3,>=2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (2.28.2)\n",
35 | "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.8.2)\n",
36 | "Requirement already satisfied: attrs>=17.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (22.2.0)\n",
37 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (3.1.0)\n",
38 | "Requirement already satisfied: frozenlist>=1.1.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.3)\n",
39 | "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.4)\n",
40 | "Requirement already satisfied: aiosignal>=1.1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
41 | "Requirement already satisfied: marshmallow<4.0.0,>=3.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (3.19.0)\n",
42 | "Requirement already satisfied: marshmallow-enum<2.0.0,>=1.5.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (1.5.1)\n",
43 | "Requirement already satisfied: typing-inspect>=0.4.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (0.8.0)\n",
44 | "Requirement already satisfied: typing-extensions>=4.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from pydantic<2,>=1->langchain) (4.5.0)\n",
45 | "Requirement already satisfied: idna<4,>=2.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (3.4)\n",
46 | "Requirement already satisfied: certifi>=2017.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (2022.12.7)\n",
47 | "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (1.26.15)\n",
48 | "Requirement already satisfied: greenlet!=0.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from SQLAlchemy<2,>=1->langchain) (2.0.2)\n",
49 | "Requirement already satisfied: packaging>=17.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (23.0)\n",
50 | "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from typing-inspect>=0.4.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (1.0.0)\n",
51 | "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.\n",
52 | "You should consider upgrading via the '/Users/wyang14/.pyenv/versions/3.9.16/bin/python -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
53 | "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n"
54 | ]
55 | }
56 | ],
57 | "source": [
58 | "%pip install langchain"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": 12,
64 | "metadata": {
65 | "id": "CcSMVHBz6zrj"
66 | },
67 | "outputs": [],
68 | "source": [
69 | "from langchain import OpenAI\n",
70 | "from langchain.chains import ConversationChain\n",
71 | "from langchain.chains.conversation.memory import ConversationBufferMemory, ConversationSummaryMemory\n",
72 | "from langchain.callbacks import get_openai_callback\n",
73 | "import os"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 13,
79 | "metadata": {
80 | "id": "yozbiUy2_RCt"
81 | },
82 | "outputs": [],
83 | "source": [
84 | "def track_tokens_usage(chain, query):\n",
85 | " with get_openai_callback() as cb:\n",
86 | " result = chain.run(query)\n",
87 | " print(f'Total tokens: {cb.total_tokens}')\n",
88 | "\n",
89 | " return result\n"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 14,
95 | "metadata": {
96 | "colab": {
97 | "base_uri": "https://localhost:8080/",
98 | "height": 373
99 | },
100 | "id": "akq_I-dn-hpd",
101 | "outputId": "317e220b-914e-45b8-e1a8-ee92c838ad77"
102 | },
103 | "outputs": [],
104 | "source": [
105 | "llm = OpenAI(\n",
106 | " temperature=0,\n",
107 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
108 | "\tmodel_name=\"text-davinci-003\"\n",
109 | ")"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 15,
115 | "metadata": {},
116 | "outputs": [],
117 | "source": [
118 | "conversation = ConversationChain(llm=llm, memory = ConversationSummaryMemory(llm=llm))"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": 16,
124 | "metadata": {
125 | "id": "pEsc6-AF-riz"
126 | },
127 | "outputs": [
128 | {
129 | "name": "stdout",
130 | "output_type": "stream",
131 | "text": [
132 | "Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary.\n",
133 | "\n",
134 | "EXAMPLE\n",
135 | "Current summary:\n",
136 | "The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good.\n",
137 | "\n",
138 | "New lines of conversation:\n",
139 | "Human: Why do you think artificial intelligence is a force for good?\n",
140 | "AI: Because artificial intelligence will help humans reach their full potential.\n",
141 | "\n",
142 | "New summary:\n",
143 | "The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential.\n",
144 | "END OF EXAMPLE\n",
145 | "\n",
146 | "Current summary:\n",
147 | "{summary}\n",
148 | "\n",
149 | "New lines of conversation:\n",
150 | "{new_lines}\n",
151 | "\n",
152 | "New summary:\n"
153 | ]
154 | }
155 | ],
156 | "source": [
157 | "print(conversation.memory.prompt.template)"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 17,
163 | "metadata": {
164 | "id": "rM_qZkMT_nw7"
165 | },
166 | "outputs": [
167 | {
168 | "name": "stdout",
169 | "output_type": "stream",
170 | "text": [
171 | "Total tokens: 560\n"
172 | ]
173 | },
174 | {
175 | "data": {
176 | "text/plain": [
177 | "\" That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there is the option of using off-chain solutions, such as sidechains or state channels, which would allow for transactions to be processed outside of the main blockchain.\""
178 | ]
179 | },
180 | "execution_count": 17,
181 | "metadata": {},
182 | "output_type": "execute_result"
183 | }
184 | ],
185 | "source": [
186 | "track_tokens_usage(conversation, \"My interest is to explore the options of scaling Ethereum\")\n"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": 23,
192 | "metadata": {
193 | "id": "mCr8e21m_njK"
194 | },
195 | "outputs": [
196 | {
197 | "name": "stdout",
198 | "output_type": "stream",
199 | "text": [
200 | "Total tokens: 1468\n"
201 | ]
202 | },
203 | {
204 | "data": {
205 | "text/plain": [
206 | "' Sure! Sharding is a scaling solution that involves splitting the blockchain into multiple shards, each of which processes transactions in parallel. This allows for more transactions to be processed at the same time, increasing the scalability of the network.\\n\\nSharding is a concept that has been around for a while, but it has only recently been applied to blockchain technology. The idea is to divide the blockchain into multiple shards, each of which processes transactions independently. This allows for more transactions to be processed in parallel, increasing the scalability of the network.\\n\\nSharding is a complex process that requires careful planning and implementation. It involves splitting the blockchain into multiple shards, each of which processes transactions independently. This allows for more transactions to be processed in parallel, increasing the scalability of the network.\\n\\nThe first step in sharding is to divide the blockchain into multiple shards. This is done by dividing the blockchain into multiple parts, each of which processes transactions independently. This allows for more transactions to be processed in parallel, increasing the scalability of the network.\\n\\nThe second step is to create a consensus mechanism for each shard. This is done by creating a consensus mechanism for each shard, which is responsible for validating transactions and ensuring the integrity of the data'"
207 | ]
208 | },
209 | "execution_count": 23,
210 | "metadata": {},
211 | "output_type": "execute_result"
212 | }
213 | ],
214 | "source": [
215 | "track_tokens_usage(conversation, \"Could you please elaborate more on sharding? Try to use at least 1000 words.\")"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": 19,
221 | "metadata": {},
222 | "outputs": [
223 | {
224 | "name": "stdout",
225 | "output_type": "stream",
226 | "text": [
227 | "Total tokens: 793\n"
228 | ]
229 | },
230 | {
231 | "data": {
232 | "text/plain": [
233 | "' Sure! There are several sharding projects currently in development for Ethereum. Some of the most popular ones include Ethereum 2.0, which is a major upgrade to the Ethereum network that will introduce sharding and other scalability improvements; Zilliqa, which is a blockchain platform that uses sharding to increase transaction throughput; and Polkadot, which is a blockchain interoperability platform that uses sharding to enable communication between different blockchains.'"
234 | ]
235 | },
236 | "execution_count": 19,
237 | "metadata": {},
238 | "output_type": "execute_result"
239 | }
240 | ],
241 | "source": [
242 | "track_tokens_usage(conversation, \"What are the cons of sharding?\")"
243 | ]
244 | },
245 | {
246 | "cell_type": "code",
247 | "execution_count": 20,
248 | "metadata": {},
249 | "outputs": [
250 | {
251 | "name": "stdout",
252 | "output_type": "stream",
253 | "text": [
254 | "Total tokens: 858\n"
255 | ]
256 | },
257 | {
258 | "data": {
259 | "text/plain": [
260 | "' State channels are a type of off-chain scaling solution that allows two or more parties to transact without having to broadcast the transaction to the entire blockchain. This allows for faster and cheaper transactions, as well as increased privacy. Examples of projects that use state channels include Raiden, Lightning Network, and Celer Network.'"
261 | ]
262 | },
263 | "execution_count": 20,
264 | "metadata": {},
265 | "output_type": "execute_result"
266 | }
267 | ],
268 | "source": [
269 | "track_tokens_usage(conversation, \"How about state channels?\")"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": 21,
275 | "metadata": {},
276 | "outputs": [
277 | {
278 | "name": "stdout",
279 | "output_type": "stream",
280 | "text": [
281 | "Total tokens: 1035\n"
282 | ]
283 | },
284 | {
285 | "data": {
286 | "text/plain": [
287 | "' Sure! Popular state channel products include Raiden, Lightning Network, and Celer Network. Raiden is an open source scaling solution for Ethereum that allows for fast, cheap, and private payments. Lightning Network is a second-layer payment protocol that enables instant, low-cost, and secure payments on the Bitcoin blockchain. Finally, Celer Network is a layer-2 scaling platform that enables fast, secure, and low-cost off-chain transactions for any blockchain.'"
288 | ]
289 | },
290 | "execution_count": 21,
291 | "metadata": {},
292 | "output_type": "execute_result"
293 | }
294 | ],
295 | "source": [
296 | "track_tokens_usage(conversation, \"Show me some popular state channel products\")"
297 | ]
298 | },
299 | {
300 | "cell_type": "code",
301 | "execution_count": 22,
302 | "metadata": {},
303 | "outputs": [
304 | {
305 | "name": "stdout",
306 | "output_type": "stream",
307 | "text": [
308 | "\n",
309 | "The human is interested in exploring the options of scaling Ethereum. The AI finds this topic interesting and explains that Ethereum is a decentralized platform built on blockchain technology. To scale Ethereum, there are several options available such as increasing the block size, using sharding, or using off-chain solutions like sidechains or state channels. The AI further elaborates on sharding, which is a scaling solution that involves splitting the blockchain into multiple shards, each of which processes transactions in parallel, allowing for more transactions to be processed at the same time and increasing the scalability of the network. The AI then provides examples of sharding projects, such as Ethereum 2.0, Zilliqa, and Polkadot, and also explains state channels, which are a type of off-chain scaling solution that allows two or more parties to transact without having to broadcast the transaction to the entire blockchain. When asked for popular state channel products, the AI mentions Raiden, Lightning Network, and Celer Network, which are open source scaling solutions for Ethereum, Bitcoin, and any blockchain respectively, allowing for fast, cheap, and private payments.\n"
310 | ]
311 | }
312 | ],
313 | "source": [
314 | "print(conversation.memory.buffer)"
315 | ]
316 | }
317 | ],
318 | "metadata": {
319 | "colab": {
320 | "authorship_tag": "ABX9TyMr1K4oquJDHksnEw+MRPeP",
321 | "include_colab_link": true,
322 | "provenance": []
323 | },
324 | "kernelspec": {
325 | "display_name": "Python 3",
326 | "name": "python3"
327 | },
328 | "language_info": {
329 | "codemirror_mode": {
330 | "name": "ipython",
331 | "version": 3
332 | },
333 | "file_extension": ".py",
334 | "mimetype": "text/x-python",
335 | "name": "python",
336 | "nbconvert_exporter": "python",
337 | "pygments_lexer": "ipython3",
338 | "version": "3.9.16"
339 | }
340 | },
341 | "nbformat": 4,
342 | "nbformat_minor": 0
343 | }
344 |
--------------------------------------------------------------------------------
/Langchain_Conversational_Chatbot.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 100,
16 | "metadata": {
17 | "id": "RdSvP1Oi7LCc"
18 | },
19 | "outputs": [
20 | {
21 | "name": "stdout",
22 | "output_type": "stream",
23 | "text": [
24 | "Requirement already satisfied: langchain in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (0.0.135)\n",
25 | "Requirement already satisfied: dataclasses-json<0.6.0,>=0.5.7 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (0.5.7)\n",
26 | "Requirement already satisfied: PyYAML>=5.4.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (6.0)\n",
27 | "Requirement already satisfied: numpy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.23.5)\n",
28 | "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (4.0.2)\n",
29 | "Requirement already satisfied: openapi-schema-pydantic<2.0,>=1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.2.4)\n",
30 | "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (8.2.2)\n",
31 | "Requirement already satisfied: SQLAlchemy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.4.47)\n",
32 | "Requirement already satisfied: requests<3,>=2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (2.28.2)\n",
33 | "Requirement already satisfied: pydantic<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.10.7)\n",
34 | "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (3.8.4)\n",
35 | "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.4)\n",
36 | "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.8.2)\n",
37 | "Requirement already satisfied: attrs>=17.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (22.2.0)\n",
38 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (3.1.0)\n",
39 | "Requirement already satisfied: aiosignal>=1.1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
40 | "Requirement already satisfied: frozenlist>=1.1.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.3)\n",
41 | "Requirement already satisfied: marshmallow<4.0.0,>=3.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (3.19.0)\n",
42 | "Requirement already satisfied: typing-inspect>=0.4.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (0.8.0)\n",
43 | "Requirement already satisfied: marshmallow-enum<2.0.0,>=1.5.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (1.5.1)\n",
44 | "Requirement already satisfied: typing-extensions>=4.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from pydantic<2,>=1->langchain) (4.5.0)\n",
45 | "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (1.26.15)\n",
46 | "Requirement already satisfied: idna<4,>=2.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (3.4)\n",
47 | "Requirement already satisfied: certifi>=2017.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (2022.12.7)\n",
48 | "Requirement already satisfied: greenlet!=0.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from SQLAlchemy<2,>=1->langchain) (2.0.2)\n",
49 | "Requirement already satisfied: packaging>=17.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (23.0)\n",
50 | "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from typing-inspect>=0.4.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (1.0.0)\n",
51 | "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.\n",
52 | "You should consider upgrading via the '/Users/wyang14/.pyenv/versions/3.9.16/bin/python -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
53 | "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n"
54 | ]
55 | }
56 | ],
57 | "source": [
58 | "%pip install langchain"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": 101,
64 | "metadata": {
65 | "id": "CcSMVHBz6zrj"
66 | },
67 | "outputs": [],
68 | "source": [
69 | "from langchain import OpenAI\n",
70 | "from langchain.chains import ConversationChain\n",
71 | "from langchain.chains.conversation.memory import ConversationBufferMemory, ConversationSummaryMemory\n",
72 | "from langchain.callbacks import get_openai_callback\n",
73 | "import os"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 102,
79 | "metadata": {
80 | "id": "yozbiUy2_RCt"
81 | },
82 | "outputs": [],
83 | "source": [
84 | "def track_tokens_usage(chain, query):\n",
85 | " with get_openai_callback() as cb:\n",
86 | " result = chain.run(query)\n",
87 | " print(f'Total tokens: {cb.total_tokens}')\n",
88 | " print(f'Requests: {cb.successful_requests}')\n",
89 | "\n",
90 | " return result\n"
91 | ]
92 | },
93 | {
94 | "cell_type": "code",
95 | "execution_count": 103,
96 | "metadata": {
97 | "colab": {
98 | "base_uri": "https://localhost:8080/",
99 | "height": 373
100 | },
101 | "id": "akq_I-dn-hpd",
102 | "outputId": "317e220b-914e-45b8-e1a8-ee92c838ad77"
103 | },
104 | "outputs": [],
105 | "source": [
106 | "llm = OpenAI(\n",
107 | " temperature=0,\n",
108 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
109 | "\tmodel_name=\"text-davinci-003\"\n",
110 | ")"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 104,
116 | "metadata": {},
117 | "outputs": [
118 | {
119 | "data": {
120 | "text/plain": [
121 | "'\\n\\nLangchain is a blockchain-based language learning platform that allows users to learn languages through a decentralized network. It uses a token-based system to reward users for their contributions to the network, such as creating content, providing feedback, and helping others learn. The platform also provides a marketplace for users to buy and sell language-related services and products.'"
122 | ]
123 | },
124 | "execution_count": 104,
125 | "metadata": {},
126 | "output_type": "execute_result"
127 | }
128 | ],
129 | "source": [
130 | "llm(\"What is Langchain?\")"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": 105,
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "data": {
140 | "text/plain": [
141 | "'\\n\\nYou asked me what you just asked me.'"
142 | ]
143 | },
144 | "execution_count": 105,
145 | "metadata": {},
146 | "output_type": "execute_result"
147 | }
148 | ],
149 | "source": [
150 | "llm(\"What did I just ask you?\")"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": 106,
156 | "metadata": {},
157 | "outputs": [],
158 | "source": [
159 | "conversation = ConversationChain(llm=llm, memory = ConversationBufferMemory())"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": 107,
165 | "metadata": {
166 | "id": "pEsc6-AF-riz"
167 | },
168 | "outputs": [
169 | {
170 | "name": "stdout",
171 | "output_type": "stream",
172 | "text": [
173 | "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
174 | "\n",
175 | "Current conversation:\n",
176 | "{history}\n",
177 | "Human: {input}\n",
178 | "AI:\n"
179 | ]
180 | }
181 | ],
182 | "source": [
183 | "print(conversation.prompt.template)"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": 108,
189 | "metadata": {
190 | "id": "rM_qZkMT_nw7"
191 | },
192 | "outputs": [
193 | {
194 | "name": "stdout",
195 | "output_type": "stream",
196 | "text": [
197 | "Total tokens: 201\n"
198 | ]
199 | },
200 | {
201 | "data": {
202 | "text/plain": [
203 | "\" That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there is the option of using off-chain solutions, such as sidechains or state channels, which would allow for transactions to be processed outside of the main blockchain.\""
204 | ]
205 | },
206 | "execution_count": 108,
207 | "metadata": {},
208 | "output_type": "execute_result"
209 | }
210 | ],
211 | "source": [
212 | "track_tokens_usage(conversation, \"My interest is to explore the options of scaling Ethereum\")\n"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": 115,
218 | "metadata": {
219 | "id": "mCr8e21m_njK"
220 | },
221 | "outputs": [
222 | {
223 | "name": "stdout",
224 | "output_type": "stream",
225 | "text": [
226 | "Total tokens: 1167\n"
227 | ]
228 | },
229 | {
230 | "data": {
231 | "text/plain": [
232 | "' Sure! Sharding is a process of splitting the blockchain into multiple shards, each of which contains a subset of the total data. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently. Additionally, sharding can help reduce the amount of data that needs to be stored on each node, as each node only needs to store the data for its own shard. This can help reduce the cost of running a node, as well as improve the scalability of the network.\\n\\nSharding is a process that can be applied to any blockchain, but it is particularly useful for blockchains that are experiencing scalability issues. By splitting the blockchain into multiple shards, each shard can process its own transactions independently, allowing for more transactions to be processed in parallel. This can help reduce the amount of data that needs to be stored on each node, as each node only needs to store the data for its own shard. Additionally, sharding can help reduce the cost of running a node, as the amount of data that needs to be stored is reduced.\\n\\nSharding can also help improve the scalability of the network, as each shard can process its own transactions independently. This means that the network can process more'"
233 | ]
234 | },
235 | "execution_count": 115,
236 | "metadata": {},
237 | "output_type": "execute_result"
238 | }
239 | ],
240 | "source": [
241 | "track_tokens_usage(conversation, \"Could you please elaborate more on sharding? Try to use at least 1000 words.\")"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 116,
247 | "metadata": {},
248 | "outputs": [
249 | {
250 | "name": "stdout",
251 | "output_type": "stream",
252 | "text": [
253 | "Total tokens: 1261\n"
254 | ]
255 | },
256 | {
257 | "data": {
258 | "text/plain": [
259 | "' The main con of sharding is that it can be difficult to implement, as it requires a significant amount of coordination between the different shards. Additionally, sharding can also lead to increased complexity, as the network needs to be able to handle multiple shards. Finally, sharding can also lead to increased security risks, as the network is more vulnerable to attacks if one of the shards is compromised.'"
260 | ]
261 | },
262 | "execution_count": 116,
263 | "metadata": {},
264 | "output_type": "execute_result"
265 | }
266 | ],
267 | "source": [
268 | "track_tokens_usage(conversation, \"What are the cons of sharding?\")"
269 | ]
270 | },
271 | {
272 | "cell_type": "code",
273 | "execution_count": 111,
274 | "metadata": {},
275 | "outputs": [
276 | {
277 | "name": "stdout",
278 | "output_type": "stream",
279 | "text": [
280 | "Total tokens: 527\n"
281 | ]
282 | },
283 | {
284 | "data": {
285 | "text/plain": [
286 | "' State channels are a type of off-chain solution that allow for transactions to be processed outside of the main blockchain. This can help improve scalability, as transactions can be processed without having to wait for them to be included in a block. Additionally, state channels can help reduce transaction costs, as they do not require miners to process the transactions. Finally, state channels can also help improve privacy, as the transactions are not visible on the main blockchain.'"
287 | ]
288 | },
289 | "execution_count": 111,
290 | "metadata": {},
291 | "output_type": "execute_result"
292 | }
293 | ],
294 | "source": [
295 | "track_tokens_usage(conversation, \"How about state channels?\")"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": 112,
301 | "metadata": {},
302 | "outputs": [
303 | {
304 | "name": "stdout",
305 | "output_type": "stream",
306 | "text": [
307 | "Total tokens: 607\n"
308 | ]
309 | },
310 | {
311 | "data": {
312 | "text/plain": [
313 | "' Sure! Some popular state channel products include Counterfactual, Raiden Network, and Connext. Counterfactual is a framework for building state channels on Ethereum. Raiden Network is a payment channel network for Ethereum. And Connext is a payment channel network for Ethereum that supports both on-chain and off-chain transactions.'"
314 | ]
315 | },
316 | "execution_count": 112,
317 | "metadata": {},
318 | "output_type": "execute_result"
319 | }
320 | ],
321 | "source": [
322 | "track_tokens_usage(conversation, \"Show me some popular state channel products\")"
323 | ]
324 | },
325 | {
326 | "cell_type": "code",
327 | "execution_count": 113,
328 | "metadata": {},
329 | "outputs": [
330 | {
331 | "name": "stdout",
332 | "output_type": "stream",
333 | "text": [
334 | "Human: My interest is to explore the options of scaling Ethereum\n",
335 | "AI: That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there is the option of using off-chain solutions, such as sidechains or state channels, which would allow for transactions to be processed outside of the main blockchain.\n",
336 | "Human: Could you please elaborate more on sharding?\n",
337 | "AI: Sure! Sharding is a process of splitting the blockchain into multiple shards, each of which contains a subset of the total data. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently. Additionally, sharding can help reduce the amount of data that needs to be stored on each node, as each node only needs to store the data for its own shard. This can help reduce the cost of running a node, as well as improve the scalability of the network.\n",
338 | "Human: Show me some sharding projects.\n",
339 | "AI: Sure! There are several projects that are currently working on sharding solutions for Ethereum. One example is the Ethereum 2.0 project, which is aiming to implement sharding on the Ethereum network. Another example is the Zilliqa project, which is a blockchain platform that uses sharding to improve scalability. Finally, there is the Polkadot project, which is a blockchain platform that uses sharding to enable interoperability between different blockchains.\n",
340 | "Human: How about state channels?\n",
341 | "AI: State channels are a type of off-chain solution that allow for transactions to be processed outside of the main blockchain. This can help improve scalability, as transactions can be processed without having to wait for them to be included in a block. Additionally, state channels can help reduce transaction costs, as they do not require miners to process the transactions. Finally, state channels can also help improve privacy, as the transactions are not visible on the main blockchain.\n",
342 | "Human: Show me some popular state channel products\n",
343 | "AI: Sure! Some popular state channel products include Counterfactual, Raiden Network, and Connext. Counterfactual is a framework for building state channels on Ethereum. Raiden Network is a payment channel network for Ethereum. And Connext is a payment channel network for Ethereum that supports both on-chain and off-chain transactions.\n"
344 | ]
345 | }
346 | ],
347 | "source": [
348 | "print(conversation.memory.buffer)"
349 | ]
350 | }
351 | ],
352 | "metadata": {
353 | "colab": {
354 | "authorship_tag": "ABX9TyMr1K4oquJDHksnEw+MRPeP",
355 | "include_colab_link": true,
356 | "provenance": []
357 | },
358 | "kernelspec": {
359 | "display_name": "Python 3",
360 | "name": "python3"
361 | },
362 | "language_info": {
363 | "codemirror_mode": {
364 | "name": "ipython",
365 | "version": 3
366 | },
367 | "file_extension": ".py",
368 | "mimetype": "text/x-python",
369 | "name": "python",
370 | "nbconvert_exporter": "python",
371 | "pygments_lexer": "ipython3",
372 | "version": "3.9.16"
373 | }
374 | },
375 | "nbformat": 4,
376 | "nbformat_minor": 0
377 | }
378 |
--------------------------------------------------------------------------------
/Langchain_Conversational_Chatbot_Memory_Types.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "colab_type": "text",
7 | "id": "view-in-github"
8 | },
9 | "source": [
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 62,
16 | "metadata": {},
17 | "outputs": [
18 | {
19 | "name": "stdout",
20 | "output_type": "stream",
21 | "text": [
22 | "Requirement already satisfied: langchain in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (0.0.135)\n",
23 | "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (4.0.2)\n",
24 | "Requirement already satisfied: pydantic<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.10.7)\n",
25 | "Requirement already satisfied: PyYAML>=5.4.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (6.0)\n",
26 | "Requirement already satisfied: dataclasses-json<0.6.0,>=0.5.7 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (0.5.7)\n",
27 | "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (3.8.4)\n",
28 | "Requirement already satisfied: numpy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.23.5)\n",
29 | "Requirement already satisfied: requests<3,>=2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (2.28.2)\n",
30 | "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (8.2.2)\n",
31 | "Requirement already satisfied: openapi-schema-pydantic<2.0,>=1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.2.4)\n",
32 | "Requirement already satisfied: SQLAlchemy<2,>=1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from langchain) (1.4.47)\n",
33 | "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.4)\n",
34 | "Requirement already satisfied: frozenlist>=1.1.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.3)\n",
35 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (3.1.0)\n",
36 | "Requirement already satisfied: attrs>=17.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (22.2.0)\n",
37 | "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.8.2)\n",
38 | "Requirement already satisfied: aiosignal>=1.1.2 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
39 | "Requirement already satisfied: typing-inspect>=0.4.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (0.8.0)\n",
40 | "Requirement already satisfied: marshmallow<4.0.0,>=3.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (3.19.0)\n",
41 | "Requirement already satisfied: marshmallow-enum<2.0.0,>=1.5.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain) (1.5.1)\n",
42 | "Requirement already satisfied: typing-extensions>=4.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from pydantic<2,>=1->langchain) (4.5.0)\n",
43 | "Requirement already satisfied: idna<4,>=2.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (3.4)\n",
44 | "Requirement already satisfied: certifi>=2017.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (2022.12.7)\n",
45 | "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from requests<3,>=2->langchain) (1.26.15)\n",
46 | "Requirement already satisfied: greenlet!=0.4.17 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from SQLAlchemy<2,>=1->langchain) (2.0.2)\n",
47 | "Requirement already satisfied: packaging>=17.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (23.0)\n",
48 | "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from typing-inspect>=0.4.0->dataclasses-json<0.6.0,>=0.5.7->langchain) (1.0.0)\n",
49 | "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.\n",
50 | "You should consider upgrading via the '/Users/wyang14/.pyenv/versions/3.9.16/bin/python -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
51 | "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n",
52 | "Requirement already satisfied: matplotlib in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (3.7.1)\n",
53 | "Requirement already satisfied: numpy>=1.20 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (1.23.5)\n",
54 | "Requirement already satisfied: pyparsing>=2.3.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (3.0.9)\n",
55 | "Requirement already satisfied: importlib-resources>=3.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (5.12.0)\n",
56 | "Requirement already satisfied: packaging>=20.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (23.0)\n",
57 | "Requirement already satisfied: pillow>=6.2.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (9.5.0)\n",
58 | "Requirement already satisfied: fonttools>=4.22.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (4.39.3)\n",
59 | "Requirement already satisfied: cycler>=0.10 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (0.11.0)\n",
60 | "Requirement already satisfied: contourpy>=1.0.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (1.0.7)\n",
61 | "Requirement already satisfied: python-dateutil>=2.7 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (2.8.2)\n",
62 | "Requirement already satisfied: kiwisolver>=1.0.1 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from matplotlib) (1.4.4)\n",
63 | "Requirement already satisfied: zipp>=3.1.0 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from importlib-resources>=3.2.0->matplotlib) (3.15.0)\n",
64 | "Requirement already satisfied: six>=1.5 in /Users/wyang14/.pyenv/versions/3.9.16/lib/python3.9/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n",
65 | "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.\n",
66 | "You should consider upgrading via the '/Users/wyang14/.pyenv/versions/3.9.16/bin/python -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
67 | "\u001b[0mNote: you may need to restart the kernel to use updated packages.\n"
68 | ]
69 | }
70 | ],
71 | "source": [
72 | "%pip install langchain\n",
73 | "%pip install matplotlib"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 63,
79 | "metadata": {
80 | "id": "CcSMVHBz6zrj"
81 | },
82 | "outputs": [],
83 | "source": [
84 | "from langchain import OpenAI\n",
85 | "from langchain.chains import ConversationChain\n",
86 | "from langchain.chains.conversation.memory import ConversationBufferMemory, ConversationSummaryMemory, ConversationBufferWindowMemory, ConversationSummaryBufferMemory\n",
87 | "from langchain.callbacks import get_openai_callback\n",
88 | "import os"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 64,
94 | "metadata": {},
95 | "outputs": [],
96 | "source": [
97 | "QUERIES = [\n",
98 | " \"My interest is to explore the options of scaling Ethereum\",\n",
99 | " \"Could you please elaborate more on sharding? Try to use at least 1000 words.\",\n",
100 | " \"What are the cons of sharding?\"\n",
101 | " \"What should I learn if I decide to work on Ethereum?\",\n",
102 | " \"What are the most important skills for a blockchain developer?\",\n",
103 | " \"I have some basic understanding of smart contracts. Other than the basic programming skills, what else should I learn? I know NFT is pretty popular, what should I be capable of doing with NFT?\",\n",
104 | " \"Opensea is one of the most popular NFT marketplace. What's its architecture? How can I build something similar?\",\n",
105 | " \"How can I run such a marketplace on Ethereum? What's the cost of running such a marketplace? I would like to know the typical business model of such a marketplace.\",\n",
106 | " \"In terms of marketing, as more and more NFT collections are published on Opensea, how can my marketplace compete with them? What's the potential opportunity for me to win the battle?\",\n",
107 | " \"What are the most popular NFT collections on Opensea? What's the typical price of a NFT collection? How can I get a NFT collection on Opensea?\"\n",
108 | "]"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": 65,
114 | "metadata": {
115 | "id": "yozbiUy2_RCt"
116 | },
117 | "outputs": [],
118 | "source": [
119 | "def track_tokens_usage(chain, query, tokens, requests):\n",
120 | " with get_openai_callback() as cb:\n",
121 | " result = chain.run(query)\n",
122 | " print(f'Total tokens: {cb.total_tokens}')\n",
123 | " print(f'Requests: {cb.successful_requests}')\n",
124 | " tokens.append(cb.total_tokens)\n",
125 | " requests.append(cb.successful_requests)\n",
126 | "\n",
127 | " return result\n"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": 71,
133 | "metadata": {},
134 | "outputs": [],
135 | "source": [
136 | "def start_conversation(llm, queries, memory_type):\n",
137 | " chain = ConversationChain(llm=llm, memory=memory_type)\n",
138 | " tokens = []\n",
139 | " requests = []\n",
140 | " for query in queries:\n",
141 | " print(f'Query: {query}')\n",
142 | " result = track_tokens_usage(chain, query, tokens, requests)\n",
143 | " print(f'Result: {result}')\n",
144 | " print('')\n",
145 | "\n",
146 | " return tokens, requests"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": 72,
152 | "metadata": {},
153 | "outputs": [
154 | {
155 | "name": "stdout",
156 | "output_type": "stream",
157 | "text": [
158 | "Query: My interest is to explore the options of scaling Ethereum\n",
159 | "Total tokens: 188\n",
160 | "Requests: 1\n",
161 | "Result: That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there are also solutions such as Plasma and Raiden Network that are being developed to help scale Ethereum.\n",
162 | "\n",
163 | "Query: Could you please elaborate more on sharding? Try to use at least 1000 words.\n",
164 | "Total tokens: 467\n",
165 | "Requests: 1\n",
166 | "Result: Sure! Sharding is a scaling solution for Ethereum that involves splitting the blockchain into multiple shards. Each shard is a separate blockchain that is connected to the main Ethereum blockchain. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently.\n",
167 | "\n",
168 | "Sharding is a relatively new concept, and it is still being developed and tested. It is expected to be implemented in Ethereum in the near future.\n",
169 | "\n",
170 | "The main idea behind sharding is to divide the blockchain into multiple shards, each of which can process its own transactions independently. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently. This also reduces the amount of data that needs to be stored on each node, as each node only needs to store the data for its own shard.\n",
171 | "\n",
172 | "Sharding also allows for more efficient use of resources, as each shard can be run on its own hardware. This means that the resources used to run the blockchain can be distributed across multiple shards, allowing for more efficient use of resources.\n",
173 | "\n",
174 | "Sharding also allows for more efficient use of network bandwidth, as each shard can be run on its own network. This means that the network bandwidth used to run the blockchain\n",
175 | "\n",
176 | "Query: What are the cons of sharding?What should I learn if I decide to work on Ethereum?\n",
177 | "Total tokens: 632\n",
178 | "Requests: 1\n",
179 | "Result: The main con of sharding is that it is a relatively new concept, and it is still being developed and tested. This means that there is a risk of bugs and security issues that could arise from the implementation of sharding.\n",
180 | "\n",
181 | "If you decide to work on Ethereum, you should learn about blockchain technology, smart contracts, and decentralized applications. You should also learn about the Ethereum Virtual Machine (EVM), which is the runtime environment for smart contracts. Additionally, you should learn about the various scaling solutions available for Ethereum, such as sharding, Plasma, and Raiden Network. Finally, you should also learn about the various tools and frameworks available for developing decentralized applications on Ethereum.\n",
182 | "\n",
183 | "Query: What are the most important skills for a blockchain developer?\n",
184 | "Total tokens: 738\n",
185 | "Requests: 1\n",
186 | "Result: The most important skills for a blockchain developer are a strong understanding of blockchain technology, cryptography, and distributed systems. Additionally, a blockchain developer should have a good understanding of smart contracts, decentralized applications, and the Ethereum Virtual Machine (EVM). They should also have experience with programming languages such as Solidity, JavaScript, and Python. Finally, they should also have experience with development tools such as Truffle, Ganache, and Remix.\n",
187 | "\n",
188 | "Query: I have some basic understanding of smart contracts. Other than the basic programming skills, what else should I learn? I know NFT is pretty popular, what should I be capable of doing with NFT?\n",
189 | "Total tokens: 975\n",
190 | "Requests: 1\n",
191 | "Result: In addition to the basic programming skills, you should also learn about the different types of smart contracts, such as ERC-20, ERC-721, and ERC-1155. You should also learn about the different tools and frameworks available for developing smart contracts, such as Truffle, Ganache, and Remix.\n",
192 | "\n",
193 | "If you want to work with NFTs, you should learn about the different types of NFTs, such as ERC-721 and ERC-1155. You should also learn about the different tools and frameworks available for developing NFTs, such as OpenZeppelin and OpenSea. Additionally, you should also learn about the different use cases for NFTs, such as digital collectibles, gaming, and digital art. Finally, you should also learn about the different platforms available for creating and trading NFTs, such as Ethereum, EOS, and NEO.\n",
194 | "\n",
195 | "Query: Opensea is one of the most popular NFT marketplace. What's its architecture? How can I build something similar?\n",
196 | "Total tokens: 1213\n",
197 | "Requests: 1\n",
198 | "Result: OpenSea is an open source platform for creating, buying, and selling non-fungible tokens (NFTs). It is built on top of the Ethereum blockchain and uses smart contracts to facilitate transactions. The architecture of OpenSea consists of a web application, a smart contract layer, and an Ethereum node. The web application is used to create and manage NFTs, while the smart contract layer is used to facilitate transactions. The Ethereum node is used to connect to the Ethereum blockchain and process transactions.\n",
199 | "\n",
200 | "If you want to build something similar to OpenSea, you should start by learning about the Ethereum blockchain and smart contracts. You should also learn about web development and the different tools and frameworks available for developing decentralized applications. Additionally, you should also learn about the different tools and frameworks available for creating and managing NFTs, such as OpenZeppelin and OpenSea. Finally, you should also learn about the different platforms available for creating and trading NFTs, such as Ethereum, EOS, and NEO.\n",
201 | "\n",
202 | "Query: How can I run such a marketplace on Ethereum? What's the cost of running such a marketplace? I would like to know the typical business model of such a marketplace.\n",
203 | "Total tokens: 1404\n",
204 | "Requests: 1\n",
205 | "Result: To run a marketplace on Ethereum, you will need to create a web application, a smart contract layer, and an Ethereum node. You will also need to create and manage NFTs, and you will need to connect to the Ethereum blockchain and process transactions. The cost of running such a marketplace will depend on the size and complexity of the marketplace, as well as the cost of running the Ethereum node.\n",
206 | "\n",
207 | "The typical business model of such a marketplace is to charge a fee for transactions. This fee is usually a percentage of the transaction amount, and it is used to cover the costs of running the marketplace. Additionally, some marketplaces may also charge a listing fee for NFTs, or they may offer premium services for a fee.\n",
208 | "\n",
209 | "Query: In terms of marketing, as more and more NFT collections are published on Opensea, how can my marketplace compete with them? What's the potential opportunity for me to win the battle?\n",
210 | "Total tokens: 1555\n",
211 | "Requests: 1\n",
212 | "Result: To compete with other NFT marketplaces, you should focus on creating a unique user experience and offering features that are not available on other marketplaces. You should also focus on marketing your marketplace to the right audience, and you should use social media and other channels to reach potential customers. Additionally, you should focus on building relationships with creators and collectors, as this will help to build trust and loyalty. Finally, you should also focus on creating a strong brand identity, as this will help to differentiate your marketplace from the competition.\n",
213 | "\n",
214 | "Query: What are the most popular NFT collections on Opensea? What's the typical price of a NFT collection? How can I get a NFT collection on Opensea?\n",
215 | "Total tokens: 1716\n",
216 | "Requests: 1\n",
217 | "Result: The most popular NFT collections on OpenSea are CryptoKitties, Decentraland, and Axie Infinity. The typical price of a NFT collection varies depending on the type of collection and the rarity of the items.\n",
218 | "\n",
219 | "To get a NFT collection on OpenSea, you can either buy it from another user or create your own collection. If you want to buy a collection, you can search for it on OpenSea and make an offer. If you want to create your own collection, you can use the OpenSea platform to create and manage your collection.\n",
220 | "\n"
221 | ]
222 | }
223 | ],
224 | "source": [
225 | "tokens1, requests1 = start_conversation(OpenAI(\n",
226 | " temperature=0,\n",
227 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
228 | "\tmodel_name=\"text-davinci-003\"\n",
229 | "), QUERIES, ConversationBufferMemory())"
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": 73,
235 | "metadata": {},
236 | "outputs": [
237 | {
238 | "name": "stdout",
239 | "output_type": "stream",
240 | "text": [
241 | "Query: My interest is to explore the options of scaling Ethereum\n",
242 | "Total tokens: 532\n",
243 | "Requests: 2\n",
244 | "Result: That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there are also solutions such as Plasma and Raiden Network that are being developed to help scale Ethereum.\n",
245 | "\n",
246 | "Query: Could you please elaborate more on sharding? Try to use at least 1000 words.\n",
247 | "Total tokens: 1014\n",
248 | "Requests: 2\n",
249 | "Result: Sure, I'd be happy to explain sharding in more detail. \n",
250 | "\n",
251 | "Sharding is a scaling solution for Ethereum that works by dividing the blockchain into multiple parts, or shards. Each shard contains its own set of transactions and is stored on a different node. This allows for more transactions to be processed in parallel, increasing the overall throughput of the network.\n",
252 | "\n",
253 | "Sharding works by dividing the blockchain into multiple parts, or shards. Each shard contains its own set of transactions and is stored on a different node. This allows for more transactions to be processed in parallel, increasing the overall throughput of the network.\n",
254 | "\n",
255 | "The idea behind sharding is to divide the blockchain into multiple parts, or shards. Each shard contains its own set of transactions and is stored on a different node. This allows for more transactions to be processed in parallel, increasing the overall throughput of the network.\n",
256 | "\n",
257 | "Sharding is a scaling solution for Ethereum that works by dividing the blockchain into multiple parts, or shards. Each shard contains its own set of transactions and is stored on a different node. This allows for more transactions to be processed in parallel, increasing the overall throughput of the network.\n",
258 | "\n",
259 | "Sharding also helps to reduce the amount of data that needs to be\n",
260 | "\n",
261 | "Query: What are the cons of sharding?What should I learn if I decide to work on Ethereum?\n",
262 | "Total tokens: 911\n",
263 | "Requests: 2\n",
264 | "Result: The main con of sharding is that it can be difficult to implement and maintain. Additionally, it can be difficult to ensure that all nodes are in sync and that the data is consistent across all shards. If you decide to work on Ethereum, you should learn about blockchain technology, smart contracts, and the Ethereum Virtual Machine. You should also become familiar with the Ethereum development tools such as Solidity, Truffle, and Web3.js.\n",
265 | "\n",
266 | "Query: What are the most important skills for a blockchain developer?\n",
267 | "Total tokens: 1098\n",
268 | "Requests: 2\n",
269 | "Result: The most important skills for a blockchain developer include a strong understanding of blockchain technology, cryptography, and distributed systems; proficiency in programming languages such as Solidity, JavaScript, and Python; and experience with development tools such as Truffle, Web3.js, and Geth. Additionally, blockchain developers should have a good understanding of the Ethereum Virtual Machine, smart contracts, and the Ethereum network.\n",
270 | "\n",
271 | "Query: I have some basic understanding of smart contracts. Other than the basic programming skills, what else should I learn? I know NFT is pretty popular, what should I be capable of doing with NFT?\n",
272 | "Total tokens: 1356\n",
273 | "Requests: 2\n",
274 | "Result: To work with Non-Fungible Tokens (NFTs), you should have a good understanding of the ERC-721 and ERC-1155 standards, which are the most commonly used standards for creating and managing NFTs. Additionally, you should be familiar with the tools and frameworks used to create and manage NFTs, such as OpenZeppelin, OpenSea, and 3Box. You should also have a good understanding of the different use cases for NFTs, such as digital collectibles, gaming, and digital art. Finally, you should have a good understanding of the different platforms and protocols used to create and manage NFTs, such as Ethereum, EOS, and NEO.\n",
275 | "\n",
276 | "Query: Opensea is one of the most popular NFT marketplace. What's its architecture? How can I build something similar?\n",
277 | "Total tokens: 1332\n",
278 | "Requests: 2\n",
279 | "Result: Opensea is an open source platform that allows users to buy, sell, and trade Non-Fungible Tokens (NFTs). It is built on the Ethereum blockchain and uses the ERC-721 and ERC-1155 standards. To build something similar, you would need to have a good understanding of the ERC-721 and ERC-1155 standards, the tools and frameworks used to create and manage NFTs, the different use cases for NFTs, and the different platforms. Additionally, you would need to be proficient in programming languages such as Solidity, JavaScript, and Python, and have experience with development tools such as Truffle, Web3.js, and Geth.\n",
280 | "\n",
281 | "Query: How can I run such a marketplace on Ethereum? What's the cost of running such a marketplace? I would like to know the typical business model of such a marketplace.\n",
282 | "Total tokens: 1332\n",
283 | "Requests: 2\n",
284 | "Result: Running a marketplace on Ethereum requires a few steps. First, you need to create a smart contract that defines the rules of the marketplace. This smart contract will need to be deployed to the Ethereum network, which will incur a cost in the form of gas fees. Once the smart contract is deployed, you will need to create a user interface for the marketplace, which can be done using a web development framework such as React.js. As for the cost of running the marketplace, it will depend on the size and complexity of the marketplace, as well as the number of transactions that will be processed. The typical business model for a marketplace on Ethereum is to charge a fee for each transaction that is processed.\n",
285 | "\n",
286 | "Query: In terms of marketing, as more and more NFT collections are published on Opensea, how can my marketplace compete with them? What's the potential opportunity for me to win the battle?\n",
287 | "Total tokens: 1276\n",
288 | "Requests: 2\n",
289 | "Result: The potential opportunity for you to win the battle in terms of marketing is to focus on creating a unique and engaging user experience. This could include offering exclusive content, discounts, or rewards for customers who purchase from your marketplace. Additionally, you could focus on building relationships with influencers and content creators to help promote your marketplace. Additionally, you could focus on creating a strong brand identity and presence on social media platforms to help increase visibility and reach. Finally, you could focus on optimizing your marketplace for search engine visibility to help increase organic traffic.\n",
290 | "\n",
291 | "Query: What are the most popular NFT collections on Opensea? What's the typical price of a NFT collection? How can I get a NFT collection on Opensea?\n",
292 | "Total tokens: 1308\n",
293 | "Requests: 2\n",
294 | "Result: The most popular NFT collections on OpenSea are CryptoKitties, Decentraland, and Axie Infinity. The typical price of a NFT collection varies depending on the type of collection and the individual pieces within it. Generally, collections range from a few dollars to thousands of dollars. To get a NFT collection on OpenSea, you can either purchase one from another user or create your own collection. To create your own collection, you will need to have the individual pieces of the collection already in your wallet. Once you have the pieces, you can create a collection on OpenSea and set the price.\n",
295 | "\n"
296 | ]
297 | }
298 | ],
299 | "source": [
300 | "llm = OpenAI(\n",
301 | " temperature=0,\n",
302 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
303 | "\tmodel_name=\"text-davinci-003\"\n",
304 | ")\n",
305 | "\n",
306 | "(tokens2, requests2) = start_conversation(llm, QUERIES, ConversationSummaryMemory(llm=llm))"
307 | ]
308 | },
309 | {
310 | "cell_type": "code",
311 | "execution_count": 74,
312 | "metadata": {},
313 | "outputs": [
314 | {
315 | "name": "stdout",
316 | "output_type": "stream",
317 | "text": [
318 | "Query: My interest is to explore the options of scaling Ethereum\n",
319 | "Total tokens: 201\n",
320 | "Requests: 1\n",
321 | "Result: That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there is the option of using off-chain solutions, such as sidechains or state channels, which would allow for transactions to be processed outside of the main blockchain.\n",
322 | "\n",
323 | "Query: Could you please elaborate more on sharding? Try to use at least 1000 words.\n",
324 | "Total tokens: 480\n",
325 | "Requests: 1\n",
326 | "Result: Sure! Sharding is a scaling solution for Ethereum that involves splitting the blockchain into multiple shards. Each shard is a separate blockchain that is connected to the main blockchain. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently.\n",
327 | "\n",
328 | "Sharding is a relatively new concept, and it is still being developed and tested. It is expected to be implemented in Ethereum in the near future.\n",
329 | "\n",
330 | "The main benefit of sharding is that it allows for more transactions to be processed in parallel. This means that the blockchain can process more transactions in a shorter amount of time, which can help to reduce transaction fees and improve scalability.\n",
331 | "\n",
332 | "Sharding also has some drawbacks. For example, it can be difficult to ensure that all of the shards are in sync with each other. This means that if one shard is not in sync with the others, it could lead to inconsistencies in the data stored on the blockchain. Additionally, sharding can be difficult to implement, as it requires a lot of coordination between the different shards.\n",
333 | "\n",
334 | "Sharding also requires a lot of computing power, as each shard needs to be able to process its own transactions independently. This means that the blockchain needs to have enough computing power to\n",
335 | "\n",
336 | "Query: What are the cons of sharding?What should I learn if I decide to work on Ethereum?\n",
337 | "Total tokens: 481\n",
338 | "Requests: 1\n",
339 | "Result: The main drawbacks of sharding are that it can be difficult to ensure that all of the shards are in sync with each other, and it can be difficult to implement. Additionally, sharding requires a lot of computing power, as each shard needs to be able to process its own transactions independently.\n",
340 | "\n",
341 | "If you decide to work on Ethereum, you should learn about blockchain technology, smart contracts, and distributed systems. You should also learn about Ethereum-specific technologies such as Solidity, Web3, and Truffle. Additionally, you should learn about sharding and other scaling solutions for Ethereum.\n",
342 | "\n",
343 | "Query: What are the most important skills for a blockchain developer?\n",
344 | "Total tokens: 311\n",
345 | "Requests: 1\n",
346 | "Result: The most important skills for a blockchain developer are a strong understanding of blockchain technology, cryptography, distributed systems, and smart contracts. Additionally, a blockchain developer should have experience with programming languages such as Solidity, JavaScript, and Python. They should also have experience with development tools such as Web3, Truffle, and Ganache. Finally, a blockchain developer should have a good understanding of security best practices and be able to identify and mitigate potential security risks.\n",
347 | "\n",
348 | "Query: I have some basic understanding of smart contracts. Other than the basic programming skills, what else should I learn? I know NFT is pretty popular, what should I be capable of doing with NFT?\n",
349 | "Total tokens: 355\n",
350 | "Requests: 1\n",
351 | "Result: To become a proficient blockchain developer, you should have a good understanding of the fundamentals of smart contracts, such as the different types of smart contracts, the different programming languages used to create them, and the different tools used to deploy them. Additionally, you should have a good understanding of the different types of NFTs, such as ERC-721 and ERC-1155, and be able to create and deploy them. You should also be familiar with the different platforms used to create and deploy NFTs, such as Ethereum, EOS, and NEO. Finally, you should have a good understanding of the different use cases for NFTs, such as digital art, gaming, and collectibles.\n",
352 | "\n",
353 | "Query: Opensea is one of the most popular NFT marketplace. What's its architecture? How can I build something similar?\n",
354 | "Total tokens: 420\n",
355 | "Requests: 1\n",
356 | "Result: OpenSea is an open source, decentralized marketplace for buying and selling non-fungible tokens (NFTs). It is built on the Ethereum blockchain and uses smart contracts to facilitate transactions. To build something similar, you would need to have a good understanding of blockchain technology, smart contracts, and the Ethereum Virtual Machine (EVM). Additionally, you would need to be familiar with the different tools and frameworks used to develop decentralized applications (dApps), such as Truffle, Web3.js, and Solidity. Finally, you would need to have a good understanding of the different protocols used to create and deploy NFTs, such as ERC-721 and ERC-1155.\n",
357 | "\n",
358 | "Query: How can I run such a marketplace on Ethereum? What's the cost of running such a marketplace? I would like to know the typical business model of such a marketplace.\n",
359 | "Total tokens: 356\n",
360 | "Requests: 1\n",
361 | "Result: To run a marketplace on Ethereum, you would need to deploy a smart contract to the Ethereum blockchain. This smart contract would be responsible for handling the transactions between buyers and sellers. The cost of running such a marketplace depends on the number of transactions and the amount of gas used to process them. The typical business model for such a marketplace is to charge a fee for each transaction. This fee is usually a percentage of the total transaction amount.\n",
362 | "\n",
363 | "Query: In terms of marketing, as more and more NFT collections are published on Opensea, how can my marketplace compete with them? What's the potential opportunity for me to win the battle?\n",
364 | "Total tokens: 320\n",
365 | "Requests: 1\n",
366 | "Result: To compete with other NFT collections on Opensea, you could focus on creating a unique user experience for your marketplace. You could also focus on creating a strong brand identity and marketing your marketplace to the right audience. Additionally, you could offer incentives such as discounts or rewards to encourage users to use your marketplace. The potential opportunity for you to win the battle is to create a marketplace that stands out from the competition and offers a unique and valuable experience to users.\n",
367 | "\n",
368 | "Query: What are the most popular NFT collections on Opensea? What's the typical price of a NFT collection? How can I get a NFT collection on Opensea?\n",
369 | "Total tokens: 335\n",
370 | "Requests: 1\n",
371 | "Result: The most popular NFT collections on Opensea vary depending on the type of collection. Some of the most popular collections include CryptoPunks, Decentraland, and CryptoKitties. The typical price of a NFT collection can range from a few dollars to thousands of dollars, depending on the type of collection and the rarity of the items. To get a NFT collection on Opensea, you can either create your own collection or purchase an existing collection from another user.\n",
372 | "\n"
373 | ]
374 | }
375 | ],
376 | "source": [
377 | "(tokens3, requests3) = start_conversation(OpenAI(\n",
378 | " temperature=0,\n",
379 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
380 | "\tmodel_name=\"text-davinci-003\"\n",
381 | "), QUERIES, ConversationBufferWindowMemory(k=1))"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": 75,
387 | "metadata": {},
388 | "outputs": [
389 | {
390 | "name": "stdout",
391 | "output_type": "stream",
392 | "text": [
393 | "Query: My interest is to explore the options of scaling Ethereum\n",
394 | "Total tokens: 201\n",
395 | "Requests: 1\n",
396 | "Result: That's an interesting topic! Ethereum is a decentralized platform that enables developers to create and deploy decentralized applications. It is built on a blockchain technology, which allows for secure and transparent transactions. To scale Ethereum, there are several options available. One option is to increase the block size, which would allow more transactions to be processed in each block. Another option is to use sharding, which would split the blockchain into multiple shards and allow for more transactions to be processed in parallel. Finally, there is the option of using off-chain solutions, such as sidechains or state channels, which would allow for transactions to be processed outside of the main blockchain.\n",
397 | "\n",
398 | "Query: Could you please elaborate more on sharding? Try to use at least 1000 words.\n",
399 | "Total tokens: 480\n",
400 | "Requests: 1\n",
401 | "Result: Sure! Sharding is a scaling solution for Ethereum that involves splitting the blockchain into multiple shards. Each shard is a separate blockchain that is connected to the main blockchain. This allows for more transactions to be processed in parallel, as each shard can process its own transactions independently.\n",
402 | "\n",
403 | "Sharding is a relatively new concept, and it is still being developed and tested. It is expected to be implemented in Ethereum in the near future.\n",
404 | "\n",
405 | "The main benefit of sharding is that it allows for more transactions to be processed in parallel. This means that the blockchain can process more transactions in a shorter amount of time, which can help to reduce transaction fees and improve scalability.\n",
406 | "\n",
407 | "Sharding also has some drawbacks. For example, it can be difficult to ensure that all of the shards are in sync with each other. This means that if one shard is not in sync with the others, it could lead to inconsistencies in the data stored on the blockchain. Additionally, sharding can be difficult to implement, as it requires a lot of coordination between the different shards.\n",
408 | "\n",
409 | "Sharding also requires a lot of computing power, as each shard needs to be able to process its own transactions independently. This means that the blockchain needs to have enough computing power to\n",
410 | "\n",
411 | "Query: What are the cons of sharding?What should I learn if I decide to work on Ethereum?\n",
412 | "Total tokens: 654\n",
413 | "Requests: 1\n",
414 | "Result: The main drawbacks of sharding are that it can be difficult to ensure that all of the shards are in sync with each other, and it requires a lot of computing power. Additionally, sharding can be difficult to implement, as it requires a lot of coordination between the different shards.\n",
415 | "\n",
416 | "If you decide to work on Ethereum, you should learn about blockchain technology, smart contracts, and decentralized applications. You should also learn about the Ethereum Virtual Machine (EVM), which is the runtime environment for smart contracts. Additionally, you should learn about the different scaling solutions available for Ethereum, such as sharding and off-chain solutions. Finally, you should also learn about the different tools and frameworks available for developing decentralized applications on Ethereum.\n",
417 | "\n",
418 | "Query: What are the most important skills for a blockchain developer?\n",
419 | "Total tokens: 1128\n",
420 | "Requests: 2\n",
421 | "Result: The most important skills for a blockchain developer are a strong understanding of blockchain technology, smart contracts, and decentralized applications. Additionally, a blockchain developer should have a good understanding of the Ethereum Virtual Machine (EVM), which is the runtime environment for smart contracts. They should also have experience with the different tools and frameworks available for developing decentralized applications on Ethereum. Finally, they should have a good understanding of the different scaling solutions available for Ethereum, such as sharding and off-chain solutions.\n",
422 | "\n",
423 | "Query: I have some basic understanding of smart contracts. Other than the basic programming skills, what else should I learn? I know NFT is pretty popular, what should I be capable of doing with NFT?\n",
424 | "Total tokens: 1520\n",
425 | "Requests: 2\n",
426 | "Result: In addition to basic programming skills, you should also learn about the different tools and frameworks available for developing smart contracts. You should also learn about the different security measures that can be taken to ensure that your smart contracts are secure. Additionally, you should learn about the different standards and protocols that are used in the Ethereum ecosystem, such as ERC-20 and ERC-721.\n",
427 | "\n",
428 | "If you want to work with NFTs, you should learn about the different standards and protocols that are used for creating and managing NFTs, such as ERC-721. You should also learn about the different tools and frameworks available for creating and managing NFTs. Additionally, you should learn about the different security measures that can be taken to ensure that your NFTs are secure.\n",
429 | "\n",
430 | "Query: Opensea is one of the most popular NFT marketplace. What's its architecture? How can I build something similar?\n",
431 | "Total tokens: 1547\n",
432 | "Requests: 2\n",
433 | "Result: OpenSea is an open source, decentralized marketplace for buying and selling non-fungible tokens (NFTs). It is built on the Ethereum blockchain and uses the ERC-721 standard for creating and managing NFTs. OpenSea's architecture consists of a set of smart contracts that handle the buying and selling of NFTs, as well as a web application that allows users to interact with the smart contracts.\n",
434 | "\n",
435 | "If you want to build something similar to OpenSea, you should start by learning about the different tools and frameworks available for developing decentralized applications on Ethereum. You should also learn about the different standards and protocols that are used for creating and managing NFTs, such as ERC-721. Additionally, you should learn about the different security measures that can be taken to ensure that your NFTs are secure. Finally, you should also learn about the different smart contracts that are used in OpenSea's architecture and how they interact with each other.\n",
436 | "\n",
437 | "Query: How can I run such a marketplace on Ethereum? What's the cost of running such a marketplace? I would like to know the typical business model of such a marketplace.\n",
438 | "Total tokens: 1718\n",
439 | "Requests: 2\n",
440 | "Result: To run a marketplace on Ethereum, you will need to create a set of smart contracts that handle the buying and selling of NFTs, as well as a web application that allows users to interact with the smart contracts. The cost of running such a marketplace will depend on the complexity of the smart contracts and the amount of computing power required to run them.\n",
441 | "\n",
442 | "The typical business model of such a marketplace is to charge a fee for each transaction that takes place on the platform. This fee can be taken from either the buyer or the seller, or a combination of both. Additionally, the marketplace can also charge a fee for listing NFTs on the platform.\n",
443 | "\n",
444 | "Query: In terms of marketing, as more and more NFT collections are published on Opensea, how can my marketplace compete with them? What's the potential opportunity for me to win the battle?\n",
445 | "Total tokens: 1858\n",
446 | "Requests: 2\n",
447 | "Result: To compete with other NFT marketplaces, you should focus on creating a unique user experience that sets your marketplace apart from the competition. You should also focus on marketing your platform to potential users, such as by creating content that highlights the features and benefits of your platform. Additionally, you should focus on building relationships with NFT creators and collectors, as this can help to increase the visibility of your platform. Finally, you should also focus on building a strong community around your platform, as this can help to create a loyal user base.\n",
448 | "\n",
449 | "Query: What are the most popular NFT collections on Opensea? What's the typical price of a NFT collection? How can I get a NFT collection on Opensea?\n",
450 | "Total tokens: 1900\n",
451 | "Requests: 2\n",
452 | "Result: The most popular NFT collections on OpenSea include CryptoKitties, CryptoPunks, and Decentraland. The typical price of a NFT collection varies depending on the type of collection and the rarity of the NFTs included in the collection.\n",
453 | "\n",
454 | "To get a NFT collection on OpenSea, you will need to create an account on the platform and then list your collection for sale. You can also purchase existing collections from other users on the platform.\n",
455 | "\n"
456 | ]
457 | }
458 | ],
459 | "source": [
460 | "llm = OpenAI(\n",
461 | " temperature=0,\n",
462 | "\topenai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
463 | "\tmodel_name=\"text-davinci-003\"\n",
464 | ")\n",
465 | "\n",
466 | "(tokens4, requests4) = start_conversation(llm, QUERIES, ConversationSummaryBufferMemory(\n",
467 | " llm=llm,\n",
468 | " max_token_limit=600\n",
469 | "))"
470 | ]
471 | },
472 | {
473 | "cell_type": "code",
474 | "execution_count": 76,
475 | "metadata": {},
476 | "outputs": [
477 | {
478 | "data": {
479 | "image/png": "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",
480 | "text/plain": [
481 | ""
482 | ]
483 | },
484 | "metadata": {},
485 | "output_type": "display_data"
486 | }
487 | ],
488 | "source": [
489 | "import matplotlib.pyplot as plt\n",
490 | "\n",
491 | "xs = range(1, len(QUERIES) + 1)\n",
492 | "plt.plot(xs, tokens1, label='Buffer Memory')\n",
493 | "plt.plot(xs, tokens2, label='Summary Memory')\n",
494 | "plt.plot(xs, tokens3, label='Buffer Window Memory')\n",
495 | "plt.plot(xs, tokens4, label='Summary Buffer Memory')\n",
496 | "\n",
497 | "plt.xlabel('Index of Queries')\n",
498 | "plt.ylabel('Tokens')\n",
499 | "plt.title('Tokens Usage')\n",
500 | "plt.legend()\n",
501 | "plt.show()"
502 | ]
503 | }
504 | ],
505 | "metadata": {
506 | "colab": {
507 | "authorship_tag": "ABX9TyMr1K4oquJDHksnEw+MRPeP",
508 | "include_colab_link": true,
509 | "provenance": []
510 | },
511 | "kernelspec": {
512 | "display_name": "Python 3",
513 | "name": "python3"
514 | },
515 | "language_info": {
516 | "codemirror_mode": {
517 | "name": "ipython",
518 | "version": 3
519 | },
520 | "file_extension": ".py",
521 | "mimetype": "text/x-python",
522 | "name": "python",
523 | "nbconvert_exporter": "python",
524 | "pygments_lexer": "ipython3",
525 | "version": "3.9.16"
526 | }
527 | },
528 | "nbformat": 4,
529 | "nbformat_minor": 0
530 | }
531 |
--------------------------------------------------------------------------------