From 815c47fe262f577a7865946c29e390d5cb1c0c79 Mon Sep 17 00:00:00 2001 From: joyenjoye
\n", + " OPENAI_API_KEY=\"your_api_key\" \n", + "
\n", + " \n", + " 替换\"your_api_key\"为你自己的 API Key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6932bd47-c6d5-4794-8102-a12b84412a93", + "metadata": {}, + "outputs": [], + "source": [ + "# 下载需要的包python-dotenv和openai\n", + "# 如果你需要查看安装过程日志,可删除 -q\n", + "!pip install -q python-dotenv\n", + "!pip install -q openai" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "10446712-9fa6-4d71-94ce-2ea4cf197e54", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import openai\n", + "from dotenv import find_dotenv, load_dotenv\n", + "\n", + "# 读取本地/项目的环境变量。\n", + "\n", + "# find_dotenv()寻找并定位.env文件的路径\n", + "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中\n", + "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ[\"OPENAI_API_KEY\"]" + ] + }, + { + "cell_type": "markdown", + "id": "1297dcd5", + "metadata": { + "tags": [] + }, + "source": [ + "## 二、对话缓存储存\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "ffa8cd26-45c5-4bae-90b2-b07d23bf3bb2", + "metadata": {}, + "source": [ + "### 2.1 英文版" + ] + }, + { + "cell_type": "markdown", + "id": "b7e77a3d-7aaa-48c1-b219-19bd6f4eb674", + "metadata": { + "tags": [] + }, + "source": [ + "#### 2.1.1 初始化对话模型" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "20ad6fe2", + "metadata": { + "height": 98 + }, + "outputs": [], + "source": [ + "from langchain.chains import ConversationChain\n", + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.memory import ConversationBufferMemory" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "88bdf13d", + "metadata": { + "height": 133 + }, + "outputs": [], + "source": [ + "# 这里我们将参数temperature设置为0.0,从而减少生成答案的随机性。\n", + "# 如果你想要每次得到不一样的有新意的答案,可以尝试增大该参数。\n", + "llm = ChatOpenAI(temperature=0.0) \n", + "\n", + "memory = ConversationBufferMemory()\n", + "\n", + "# 新建一个 ConversationChain Class 实例\n", + "# verbose参数设置为True时,程序会输出更详细的信息,以提供更多的调试或运行时信息。\n", + "# 相反,当将verbose参数设置为False时,程序会以更简洁的方式运行,只输出关键的信息。\n", + "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )" + ] + }, + { + "cell_type": "markdown", + "id": "dea83837", + "metadata": { + "tags": [] + }, + "source": [ + "#### 2.1.2 第一轮对话" + ] + }, + { + "cell_type": "markdown", + "id": "1a3b4c42", + "metadata": {}, + "source": [ + "当我们运行预测(predict)时,生成了一些提示,如下所见,他说“以下是人类和AI之间友好的对话,AI健谈“等等,这实际上是LangChain生成的提示,以使系统进行希望和友好的对话,并且必须保存对话,并提示了当前已完成的模型链。" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "db24677d", + "metadata": { + "height": 47 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "\n", + "Human: Hi, my name is Andrew\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "\"Hello Andrew! It's nice to meet you. How can I assist you today?\"" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"Hi, my name is Andrew\")" + ] + }, + { + "cell_type": "markdown", + "id": "e71564ad", + "metadata": {}, + "source": [ + "#### 2.1.3 第二轮对话" + ] + }, + { + "cell_type": "markdown", + "id": "54d006bd", + "metadata": {}, + "source": [ + "当我们进行第二轮对话时,它会保留上面的提示" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "cc3ef937", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "Human: Hi, my name is Andrew\n", + "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", + "Human: What is 1+1?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'1+1 is equal to 2.'" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"What is 1+1?\")" + ] + }, + { + "cell_type": "markdown", + "id": "33cb734b", + "metadata": {}, + "source": [ + "#### 2.1.4 第三轮对话" + ] + }, + { + "cell_type": "markdown", + "id": "0393df3d", + "metadata": {}, + "source": [ + "为了验证他是否记忆了前面的对话内容,我们让他回答前面已经说过的内容(我的名字),可以看到他确实输出了正确的名字,因此这个对话链随着往下进行会越来越长" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "acf3339a", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "Human: Hi, my name is Andrew\n", + "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", + "Human: What is 1+1?\n", + "AI: 1+1 is equal to 2.\n", + "Human: What is my name?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'Your name is Andrew.'" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"What is my name?\")" + ] + }, + { + "cell_type": "markdown", + "id": "5a96a8d9", + "metadata": {}, + "source": [ + "#### 2.1.5 查看储存缓存\n", + "\n", + "储存缓存(memory.buffer)\n", + "储存了当前为止所有的对话信息" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "2529400d", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Human: Hi, my name is Andrew\n", + "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", + "Human: What is 1+1?\n", + "AI: 1+1 is equal to 2.\n", + "Human: What is my name?\n", + "AI: Your name is Andrew.\n" + ] + } + ], + "source": [ + "print(memory.buffer) " + ] + }, + { + "cell_type": "markdown", + "id": "0b5de846", + "metadata": {}, + "source": [ + "也可以通过memory.load_memory_variables({})打印缓存中的历史消息。这里的`{}`是一个空字典,有一些更高级的功能,使用户可以使用更复杂的输入,但我们不会在这个短期课程中讨论它们,所以不要担心为什么这里有一个空的花括号。" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "5018cb0a", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'history': \"Human: Hi, my name is Andrew\\nAI: Hello Andrew! It's nice to meet you. How can I assist you today?\\nHuman: What is 1+1?\\nAI: 1+1 is equal to 2.\\nHuman: What is my name?\\nAI: Your name is Andrew.\"}\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({}))" + ] + }, + { + "cell_type": "markdown", + "id": "07d2e892", + "metadata": {}, + "source": [ + "#### 2.1.6 直接添加内容到储存缓存" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "14219b70", + "metadata": { + "height": 31 + }, + "outputs": [], + "source": [ + "memory = ConversationBufferMemory() # 新建一个空的对话缓存记忆" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "a36e9905", + "metadata": { + "height": 48 + }, + "outputs": [], + "source": [ + "memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"}) # 向缓存区添加指定对话的输入输出" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "61631b1f", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Human: Hi\n", + "AI: What's up\n" + ] + } + ], + "source": [ + "print(memory.buffer) # 查看缓存区结果" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "a2fdf9ec", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'history': \"Human: Hi\\nAI: What's up\"}\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({}))# 再次加载记忆变量" + ] + }, + { + "cell_type": "markdown", + "id": "2ac544f2", + "metadata": {}, + "source": [ + "继续添加新的内容,对话历史都保存下来在了!" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "7ca79256", + "metadata": { + "height": 64 + }, + "outputs": [], + "source": [ + "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "890a4497", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': \"Human: Hi\\nAI: What's up\\nHuman: Not much, just hanging\\nAI: Cool\"}" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "6eddd91a-bf1c-4b82-b99c-c585420e4ecb", + "metadata": {}, + "source": [ + "### 2.2 中文版" + ] + }, + { + "cell_type": "markdown", + "id": "55b3e4e9-7a6a-4a09-9ac3-0096a67849c7", + "metadata": {}, + "source": [ + "#### 2.1.1 初始化对话模型" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "3577aaff-7edb-40b0-866a-e407e63d55e0", + "metadata": { + "height": 98 + }, + "outputs": [], + "source": [ + "from langchain.chains import ConversationChain\n", + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.memory import ConversationBufferMemory" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "a77d37ab-1f75-4ae8-8d7c-5066773ead81", + "metadata": { + "height": 133 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "\n", + "Human: 你好, 我叫皮皮鲁\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "llm = ChatOpenAI(temperature=0.0) \n", + "\n", + "memory = ConversationBufferMemory()\n", + "\n", + "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )" + ] + }, + { + "cell_type": "markdown", + "id": "747cb539-abc4-4e47-8cb9-1ee608ab07fc", + "metadata": {}, + "source": [ + "#### 2.1.2 第一轮对话" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99e48462-7a92-4842-bdaa-2a478ba2252c", + "metadata": {}, + "outputs": [], + "source": [ + "conversation.predict(input=\"你好, 我叫皮皮鲁\")" + ] + }, + { + "cell_type": "markdown", + "id": "979d320b-6b20-4722-99db-c48a43711d6c", + "metadata": {}, + "source": [ + "#### 2.1.3 第二轮对话" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "6ed6e97a-d7ea-4188-a6d7-f91d2a29d14a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "Human: 你好, 我叫皮皮鲁\n", + "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", + "Human: 1+1等于多少?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'1+1等于2。'" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"1+1等于多少?\")" + ] + }, + { + "cell_type": "markdown", + "id": "8a1fd531-216e-42d8-b226-839747ad7dd3", + "metadata": {}, + "source": [ + "#### 2.1.4 第三轮对话" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5dfe488-2758-42c7-9c20-e483b4c22ab8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "Human: 你好, 我叫皮皮鲁\n", + "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", + "Human: 1+1等于多少?\n", + "AI: 1+1等于2。\n", + "Human: What is my name?\n", + "AI: 你的名字是皮皮鲁。\n", + "Human: 我叫什么名字?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'你叫皮皮鲁。'" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"我叫什么名字?\")" + ] + }, + { + "cell_type": "markdown", + "id": "05d9822e-943d-4905-a1f8-a0d28c215d60", + "metadata": {}, + "source": [ + "#### 2.1.5 查看储存缓存" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "0795580f-b6b6-47e0-8882-26fe204560bd", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Human: 你好, 我叫皮皮鲁\n", + "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", + "Human: 1+1等于多少?\n", + "AI: 1+1等于2。\n", + "Human: What is my name?\n", + "AI: 你的名字是皮皮鲁。\n", + "Human: 我叫什么名字?\n", + "AI: 你叫皮皮鲁。\n" + ] + } + ], + "source": [ + "print(memory.buffer) " + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "dfe7824f-bd6e-4b95-92e2-1c85c62a92e9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Human: 你好, 我叫皮皮鲁\n", + "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", + "Human: 1+1等于多少?\n", + "AI: 1+1等于2。\n", + "Human: What is my name?\n", + "AI: 你的名字是皮皮鲁。\n", + "Human: 我叫什么名字?\n", + "AI: 你叫皮皮鲁。\n" + ] + } + ], + "source": [ + "print(memory.buffer) " + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "48942759-8afb-4aed-80c5-a48952a2b0c0", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'history': 'Human: 你好, 我叫皮皮鲁\\nAI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\\nHuman: 1+1等于多少?\\nAI: 1+1等于2。\\nHuman: What is my name?\\nAI: 你的名字是皮皮鲁。\\nHuman: 我叫什么名字?\\nAI: 你叫皮皮鲁。'}\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({}))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "4d0c4625-e928-45dc-b8da-4ab865ac5f7e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: 你好, 我叫皮皮鲁\\nAI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\\nHuman: 1+1等于多少?\\nAI: 1+1等于2。\\nHuman: What is my name?\\nAI: 你的名字是皮皮鲁。\\nHuman: 我叫什么名字?\\nAI: 你叫皮皮鲁。'}" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "80f3778e-5fbf-43ed-9df1-d57d98ec6fb0", + "metadata": {}, + "source": [ + "#### 2.1.6 直接添加内容到储存缓存" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "147b2c30-1662-4b49-aaf8-c228428e5cc6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西'}" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory = ConversationBufferMemory()\n", + "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "6b5e27f0-dad7-41b6-9326-bebf6299638f", + "metadata": { + "height": 64 + }, + "outputs": [], + "source": [ + "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "cfa7c555-06ab-4906-b3dc-906f789e08f5", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool'}" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "deb33de8-37ea-4180-a73e-0fc456b14eb0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool\\nHuman: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "10146f1a-0114-4902-8122-d19ae6f7c461", + "metadata": {}, + "source": [ + "### 2.3 总结" + ] + }, + { + "cell_type": "markdown", + "id": "2759b6bc-edb2-4cfe-b0f8-1bf6c4d796f9", + "metadata": {}, + "source": [ + "当我们在使用大型语言模型进行聊天对话时,**大型语言模型本身实际上是无状态的。语言模型本身并不记得到目前为止的历史对话**。每次调用API结点都是独立的。储存(Memory)可以储存到目前为止的所有术语或对话,并将其输入或附加上下文到LLM中用于生成输出。如此看起来就好像它在进行下一轮对话的时候,记得之前说过什么。\n" + ] + }, + { + "cell_type": "markdown", + "id": "cf98e9ff", + "metadata": {}, + "source": [ + "## 三、对话缓存窗口储存\n", + " \n", + "随着对话变得越来越长,所需的内存量也变得非常长。将大量的tokens发送到LLM的成本,也会变得更加昂贵,这也就是为什么API的调用费用,通常是基于它需要处理的tokens数量而收费的。\n", + " \n", + "针对以上问题,LangChain也提供了几种方便的储存方式来保存历史对话。其中,对话缓存窗口储存只保留一个窗口大小的对话。它只使用最近的n次交互。这可以用于保持最近交互的滑动窗口,以便缓冲区不会过大" + ] + }, + { + "cell_type": "markdown", + "id": "b63c9061-9916-4524-b497-93a0aa2b7d06", + "metadata": {}, + "source": [ + "### 3.1 英文版" + ] + }, + { + "cell_type": "markdown", + "id": "641477a4", + "metadata": {}, + "source": [ + "#### 3.1.1 添加两轮对话到窗口储存" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "3ea6233e", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "from langchain.memory import ConversationBufferWindowMemory\n", + "\n", + "# k 为窗口参数,k=1表明只保留一个对话记忆\n", + "memory = ConversationBufferWindowMemory(k=1) " + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "dc4553fb", + "metadata": { + "height": 115 + }, + "outputs": [], + "source": [ + "# 向memory添加两轮对话\n", + "memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"})\n", + "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "6a788403", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: Not much, just hanging\\nAI: Cool'}" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 并查看记忆变量当前的记录\n", + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "63bda148", + "metadata": {}, + "source": [ + "#### 3.1.2 在对话链中应用窗口储存" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "4087bc87", + "metadata": { + "height": 133 + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0.0)\n", + "memory = ConversationBufferWindowMemory(k=1)\n", + "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )" + ] + }, + { + "cell_type": "markdown", + "id": "b6d661e3", + "metadata": {}, + "source": [ + "注意此处!由于这里用的是一个窗口的记忆,因此只能保存一轮的历史消息,因此AI并不能知道你第一轮对话中提到的名字,他最多只能记住上一轮(第二轮)的对话信息" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "4faaa952", + "metadata": { + "height": 47 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\"Hello Andrew! It's nice to meet you. How can I assist you today?\"" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"Hi, my name is Andrew\")" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "bb20ddaa", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1+1 is equal to 2.'" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"What is 1+1?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "489b2194", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\"I'm sorry, but I don't have access to personal information.\"" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"What is my name?\")" + ] + }, + { + "cell_type": "markdown", + "id": "88837e7c-cf4b-469e-b820-bbfc49ba876c", + "metadata": {}, + "source": [ + "### 3.2 中文版" + ] + }, + { + "cell_type": "markdown", + "id": "760ec3ad-6959-4a36-b1b5-4fcafe8088ad", + "metadata": {}, + "source": [ + "#### 3.1.1 添加两轮对话到窗口储存" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "68a2907c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'Human: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from langchain.memory import ConversationBufferWindowMemory\n", + "\n", + "# k=1表明只保留一个对话记忆\n", + "memory = ConversationBufferWindowMemory(k=1) \n", + "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", + "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "dcabf017-5bfd-4904-9f06-388f994eddc9", + "metadata": {}, + "source": [ + "#### 3.1.2 在对话链中应用窗口储存" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "1ee854d9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", + "1+1等于2。\n", + "很抱歉,我无法知道您的名字。\n" + ] + } + ], + "source": [ + "llm = ChatOpenAI(temperature=0.0)\n", + "memory = ConversationBufferWindowMemory(k=1)\n", + "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )\n", + "print(conversation.predict(input=\"你好, 我叫皮皮鲁\"))\n", + "print(conversation.predict(input=\"1+1等于多少?\"))\n", + "print(conversation.predict(input=\"我叫什么名字?\"))" + ] + }, + { + "cell_type": "markdown", + "id": "d2931b92", + "metadata": {}, + "source": [ + "## 四、对话token缓存储存" + ] + }, + { + "cell_type": "markdown", + "id": "dff5b4c7", + "metadata": {}, + "source": [ + "使用对话token缓存记忆,内存将限制保存的token数量。如果token数量超出指定数目,它会切掉这个对话的早期部分\n", + "以保留与最近的交流相对应的token数量,但不超过token限制。" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "9f6d063c", + "metadata": { + "height": 31 + }, + "outputs": [], + "source": [ + "!pip install -q tiktoken " + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "fb9020ed", + "metadata": { + "height": 81 + }, + "outputs": [], + "source": [ + "from langchain.llms import OpenAI\n", + "from langchain.memory import ConversationTokenBufferMemory" + ] + }, + { + "cell_type": "markdown", + "id": "f3a84112", + "metadata": {}, + "source": [ + "### 4.1 英文版\n", + "添加对话到Token缓存储存,限制token数量,进行测试" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "43582ee6", + "metadata": { + "height": 149 + }, + "outputs": [], + "source": [ + "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", + "memory.save_context({\"input\": \"AI is what?!\"}, {\"output\": \"Amazing!\"})\n", + "memory.save_context({\"input\": \"Backpropagation is what?\"}, {\"output\": \"Beautiful!\"})\n", + "memory.save_context({\"input\": \"Chatbots are what?\"}, {\"output\": \"Charming!\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "284288e1", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'AI: Beautiful!\\nHuman: Chatbots are what?\\nAI: Charming!'}" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "7b62b2e1", + "metadata": {}, + "source": [ + "可以看到前面超出的的token已经被舍弃了!!!" + ] + }, + { + "cell_type": "markdown", + "id": "f7f6be43", + "metadata": {}, + "source": [ + "### 4.2 中文版" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "e9191020", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': 'AI: 轻舟已过万重山。'}" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", + "memory.save_context({\"input\": \"朝辞白帝彩云间,\"}, {\"output\": \"千里江陵一日还。\"})\n", + "memory.save_context({\"input\": \"两岸猿声啼不住,\"}, {\"output\": \"轻舟已过万重山。\"})\n", + "memory.load_memory_variables({})" + ] + }, + { + "cell_type": "markdown", + "id": "fb08ef4a-876f-422a-81f9-4805288e5955", + "metadata": {}, + "source": [ + "### 4.3 补充" + ] + }, + { + "cell_type": "markdown", + "id": "5e4d918b", + "metadata": {}, + "source": [ + "ChatGPT使用一种基于字节对编码(Byte Pair Encoding,BPE)的方法来进行tokenization(将输入文本拆分为token)。BPE是一种常见的tokenization技术,它将输入文本分割成较小的子词单元。 \n", + "\n", + "OpenAI在其官方GitHub上公开了一个最新的开源Python库 [tiktoken](https://github.com/openai/tiktoken),这个库主要是用来计算tokens数量的。相比较HuggingFace的tokenizer,其速度提升了好几倍。\n", + "\n", + "具体token计算方式,特别是汉字和英文单词的token区别,具体课参考[知乎文章](https://www.zhihu.com/question/594159910) 。" + ] + }, + { + "cell_type": "markdown", + "id": "5ff55d5d", + "metadata": {}, + "source": [ + "## 五、对话摘要缓存储存" + ] + }, + { + "cell_type": "markdown", + "id": "7d39b83a", + "metadata": {}, + "source": [ + "对话摘要缓存储存,**使用LLM编写到目前为止历史对话的摘要**,并将其保存" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "72dcf8b1", + "metadata": { + "height": 64 + }, + "outputs": [], + "source": [ + "from langchain.chains import ConversationChain\n", + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.memory import ConversationSummaryBufferMemory" + ] + }, + { + "cell_type": "markdown", + "id": "243b213e-ce17-46a0-8652-03658ca58dd8", + "metadata": {}, + "source": [ + "### 5.1 英文版" + ] + }, + { + "cell_type": "markdown", + "id": "6572ef39", + "metadata": {}, + "source": [ + "#### 5.1.1 使用对话摘要缓存储存\n", + "\n", + "创建一个长字符串,其中包含某人的日程安排" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "4a5b238f", + "metadata": { + "height": 285 + }, + "outputs": [], + "source": [ + "# 创建一个长字符串\n", + "schedule = \"There is a meeting at 8am with your product team. \\\n", + "You will need your powerpoint presentation prepared. \\\n", + "9am-12pm have time to work on your LangChain \\\n", + "project which will go quickly because Langchain is such a powerful tool. \\\n", + "At Noon, lunch at the italian resturant with a customer who is driving \\\n", + "from over an hour away to meet you to understand the latest in AI. \\\n", + "Be sure to bring your laptop to show the latest LLM demo.\"\n", + "\n", + "# 使用对话摘要缓存记忆\n", + "llm = ChatOpenAI(temperature=0.0)\n", + "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100) \n", + "memory.save_context({\"input\": \"Hello\"}, {\"output\": \"What's up\"})\n", + "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})\n", + "memory.save_context(\n", + " {\"input\": \"What is on the schedule today?\"}, {\"output\": f\"{schedule}\"}\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "15226a41-ab36-43a0-93f7-c03c6b374936", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({})['history'])" + ] + }, + { + "cell_type": "markdown", + "id": "7ccb97b6", + "metadata": {}, + "source": [ + "#### 5.1.2 基于对话摘要缓存储存的对话链\n", + "基于上面的对话摘要缓存储存,新建一个对话链" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "id": "6728edba", + "metadata": { + "height": 99 + }, + "outputs": [], + "source": [ + "conversation = ConversationChain(llm=llm, memory=memory, verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "id": "9a221b1d", + "metadata": { + "height": 47 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n", + "Human: What would be a good demo to show?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.'" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"What would be a good demo to show?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "bb582617", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting. A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({})['history'])" + ] + }, + { + "cell_type": "markdown", + "id": "4ba827aa", + "metadata": { + "height": 31 + }, + "source": [ + "### 5.2 中文版" + ] + }, + { + "cell_type": "markdown", + "id": "64898f33-c538-4e68-b008-7123870b692b", + "metadata": {}, + "source": [ + "#### 5.2.1 使用对话摘要缓存储存\n", + "\n", + "创建一个长字符串,其中包含某人的日程安排" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "2c07922b", + "metadata": { + "height": 31 + }, + "outputs": [], + "source": [ + "# 创建一个长字符串\n", + "schedule = \"在八点你和你的产品团队有一个会议。 \\\n", + "你需要做一个PPT。 \\\n", + "上午9点到12点你需要忙于LangChain。\\\n", + "Langchain是一个有用的工具,因此你的项目进展的非常快。\\\n", + "中午,在意大利餐厅与一位开车来的顾客共进午餐 \\\n", + "走了一个多小时的路程与你见面,只为了解最新的 AI。 \\\n", + "确保你带了笔记本电脑可以展示最新的 LLM 样例.\"\n", + "\n", + "llm = ChatOpenAI(temperature=0.0)\n", + "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)\n", + "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", + "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", + "memory.save_context({\"input\": \"今天的日程安排是什么?\"}, {\"output\": f\"{schedule}\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "id": "17424a12-430f-4529-9067-300978c6169e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n" + ] + } + ], + "source": [ + "print(memory.load_memory_variables({})['history'])" + ] + }, + { + "cell_type": "markdown", + "id": "9e29a956-607a-4247-9eb5-01285a370991", + "metadata": {}, + "source": [ + "#### 5.1.2 基于对话摘要缓存储存的对话链\n", + "基于上面的对话摘要缓存储存,新建一个对话链" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "52696c8c", + "metadata": { + "height": 31 + }, + "outputs": [], + "source": [ + "conversation = ConversationChain(llm=llm, memory=memory, verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "id": "48690d13", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", + "\n", + "Current conversation:\n", + "System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n", + "Human: 展示什么样的样例最好呢?\n", + "AI:\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'展示一些具有多样性和创新性的样例可能是最好的选择。你可以选择展示一些基于图像识别的样例,比如人脸识别、物体识别等。另外,你也可以展示一些自然语言处理方面的样例,比如文本生成、情感分析等。最重要的是选择那些能够展示出你们团队的技术实力和创造力的样例。'" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conversation.predict(input=\"展示什么样的样例最好呢?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "85bba1f8", + "metadata": { + "height": 31 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'history': \"System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples. The human asks what kind of samples would be best to showcase. The AI suggests that showcasing diverse and innovative samples would be the best choice. They recommend selecting samples based on image recognition, such as face recognition and object recognition. Additionally, they suggest showcasing samples related to natural language processing, such as text generation and sentiment analysis. The AI emphasizes the importance of choosing samples that demonstrate the team's technical expertise and creativity.\"}" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.load_memory_variables({}) # 摘要记录更新了" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/content/LangChain for LLM Application Development/3.存储 Memory.ipynb b/content/LangChain for LLM Application Development/3.存储 Memory.ipynb deleted file mode 100644 index 6efeba6..0000000 --- a/content/LangChain for LLM Application Development/3.存储 Memory.ipynb +++ /dev/null @@ -1 +0,0 @@ -{"cells":[{"cell_type":"markdown","id":"a786c77c","metadata":{"jp-MarkdownHeadingCollapsed":true,"tags":[]},"source":["# 第三章 储存\n","\n"," - [一、设置OpenAI API Key](#一、设置OpenAI-API-Key)\n"," - [二、对话缓存储存 ](#二、对话缓存储存--)\n"," - [2.1 开始对话,第一轮](#2.1-开始对话,第一轮)\n"," - [2.2 第二轮对话](#2.2-第二轮对话)\n"," - [2.3 第三轮对话](#2.3-第三轮对话)\n"," - [2.4 .memory.buffer存储了当前为止所有的对话信息](#2.4-.memory.buffer存储了当前为止所有的对话信息)\n"," - [2.5 也可以通过memory.load_memory_variables({})打印历史消息](#2.5-也可以通过memory.load_memory_variables({})打印历史消息)\n"," - [2.6 添加指定的输入输出内容到记忆缓存区](#2.6-添加指定的输入输出内容到记忆缓存区)\n"," - [三、对话缓存窗口储存](#三、对话缓存窗口储存)\n"," - [3.1 向memory添加两轮对话,并查看记忆变量当前的记录](#3.1-向memory添加两轮对话,并查看记忆变量当前的记录)\n"," - [3.2 在看一个例子,发现和上面的结果一样,只保留了一轮对话记忆](#3.2-在看一个例子,发现和上面的结果一样,只保留了一轮对话记忆)\n"," - [3.3 将对话缓存窗口记忆应用到对话链中](#3.3-将对话缓存窗口记忆应用到对话链中)\n"," - [四、对话token缓存储存](#四、对话token缓存储存)\n"," - [4.1 导入相关包和API密钥](#4.1-导入相关包和API密钥)\n"," - [4.2 限制token数量,进行测试](#4.2-限制token数量,进行测试)\n"," - [4.3 中文例子](#4.3-中文例子)\n"," - [五、对话摘要缓存储存](#五、对话摘要缓存储存)\n"," - [5.1 创建一个长字符串,其中包含某人的日程安排](#5.1-创建一个长字符串,其中包含某人的日程安排)\n"," - [5.2 基于上面的memory,新建一个对话链](#5.2-基于上面的memory,新建一个对话链)\n"," - [5.3 中文例子](#5.3-中文例子)\n"]},{"cell_type":"markdown","id":"7e10db6f","metadata":{},"source":["当你与那些语言模型进行交互的时候,他们不会记得你之前和他进行的交流内容,这在我们构建一些应用程序(如聊天机器人)的时候,是一个很大的问题---显得不够智能!因此,在本节中我们将介绍 LangChain 中的储存模块,即如何将先前的对话嵌入到语言模型中的,使其具有连续对话的能力。\n","\n","当使用 LangChain 中的储存模块时,它可以帮助保存和管理历史聊天消息,以及构建关于特定实体的知识。这些组件可以跨多轮对话存储信息,并允许在对话期间跟踪特定信息和上下文。LangChain 提供了多种储存类型。其中,缓冲区储存允许保留最近的聊天消息,摘要储存则提供了对整个对话的摘要。实体储存则允许在多轮对话中保留有关特定实体的信息。这些记忆组件都是模块化的,可与其他组件组合使用,从而增强机器人的对话管理能力。储存模块可以通过简单的API调用来访问和更新,允许开发人员更轻松地实现对话历史记录的管理和维护。\n","\n","此次课程主要介绍其中四种记忆模块,其他模块可查看文档学习。\n","- 对话缓存记忆 (ConversationBufferMemory)\n","- 对话缓存窗口记忆 (ConversationBufferWindowMemory)\n","- 对话令牌缓存记忆 (ConversationTokenBufferMemory)\n","- 对话摘要缓存记忆 (ConversationSummaryBufferMemory)\n","\n","在LangChain中,Memory指的是大语言模型(LLM)的短期记忆。为什么是短期记忆?那是因为LLM训练好之后(获得了一些长期记忆),它的参数便不会因为用户的输入而发生改变。当用户与训练好的LLM进行对话时,LLM会暂时记住用户的输入和它已经生成的输出,以便预测之后的输出,而模型输出完毕后,它便会“遗忘”之前用户的输入和它的输出。因此,之前的这些信息只能称作为LLM的短期记忆。 \n"," \n","为了延长LLM短期记忆的保留时间,则需要借助一些外部存储方式来进行记忆,以便在用户与LLM对话中,LLM能够尽可能的知道用户与它所进行的历史对话信息。 "]},{"cell_type":"markdown","id":"1ca56e6b-1e07-4405-a1ca-f4237f20fa75","metadata":{"tags":[]},"source":["## 一、设置OpenAI API Key\n","\n","登陆 [OpenAI 账户](https://platform.openai.com/account/api-keys) 获取API Key,然后将其设置为环境变量。\n","\n","- 如果你想要设置为全局环境变量,可以参考[知乎文章](https://zhuanlan.zhihu.com/p/627665725)。\n","- 如果你想要设置为本地/项目环境变量,在本文件目录下创建`.env`文件, 打开文件输入以下内容。\n","\n","\n"," OPENAI_API_KEY=\"your_api_key\" \n","
\n"," \n"," 替换\"your_api_key\"为你自己的 API Key"]},{"cell_type":"code","execution_count":null,"id":"6932bd47-c6d5-4794-8102-a12b84412a93","metadata":{},"outputs":[],"source":["# 下载需要的包python-dotenv和openai\n","# 如果你需要查看安装过程日志,可删除 -q \n","!pip install -q python-dotenv\n","!pip install -q openai"]},{"cell_type":"code","execution_count":6,"id":"10446712-9fa6-4d71-94ce-2ea4cf197e54","metadata":{},"outputs":[],"source":["import os\n","import openai\n","from dotenv import load_dotenv, find_dotenv\n","\n","# 读取本地/项目的环境变量。\n","\n","# find_dotenv()寻找并定位.env文件的路径\n","# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n","# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n","_ = load_dotenv(find_dotenv())\n","\n","# 获取环境变量 OPENAI_API_KEY\n","openai.api_key = os.environ['OPENAI_API_KEY'] \n"]},{"cell_type":"markdown","id":"1297dcd5","metadata":{},"source":["## 二、对话缓存储存 \n"," \n","这种记忆允许存储消息,然后从变量中提取消息。"]},{"cell_type":"code","execution_count":2,"id":"20ad6fe2","metadata":{"height":98},"outputs":[],"source":["from langchain.chat_models import ChatOpenAI\n","from langchain.chains import ConversationChain\n","from langchain.memory import ConversationBufferMemory"]},{"cell_type":"code","execution_count":31,"id":"88bdf13d","metadata":{"height":133},"outputs":[],"source":["# 英文链\n","llm = ChatOpenAI(temperature=0.0) #temperature:预测下一个token时,概率越大的值就越平滑(平滑也就是让差异大的值之间的差异变得没那么大),temperature值越小则生成的内容越稳定\n","memory = ConversationBufferMemory()\n","conversation = ConversationChain( #新建一个对话链(关于链后面会提到更多的细节)\n"," llm=llm, \n"," memory = memory,\n"," verbose=True #查看Langchain实际上在做什么,设为FALSE的话只给出回答,看到不到下面绿色的内容\n",")"]},{"cell_type":"code","execution_count":32,"id":"bb4968d9","metadata":{},"outputs":[],"source":["# 中文链\n","llm = ChatOpenAI(temperature=0.0) #temperature:预测下一个token时,概率越大的值就越平滑(平滑也就是让差异大的值之间的差异变得没那么大),temperature值越小则生成的内容越稳定\n","memory_zh = ConversationBufferMemory()\n","conversation_zh = ConversationChain( #新建一个对话链(关于链后面会提到更多的细节)\n"," llm=llm, \n"," memory = memory_zh,\n"," verbose=True #查看Langchain实际上在做什么,设为FALSE的话只给出回答,看到不到下面绿色的内容\n",")"]},{"cell_type":"markdown","id":"dea83837","metadata":{},"source":["### 2.1 开始对话,第一轮"]},{"cell_type":"markdown","id":"1a3b4c42","metadata":{},"source":["当我们运行predict时,生成了一些提示,如下所见,他说“以下是人类和AI之间友好的对话,AI健谈“等等,这实际上是LangChain生成的提示,以使系统进行希望和友好的对话,并且必须保存对话,并提示了当前已完成的模型链。"]},{"cell_type":"code","execution_count":33,"id":"db24677d","metadata":{"height":47},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","\n","Human: Hi, my name is Andrew\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["\"Hello Andrew! It's nice to meet you. How can I assist you today?\""]},"execution_count":33,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"Hi, my name is Andrew\")"]},{"cell_type":"code","execution_count":34,"id":"154561c9","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","\n","Human: 你好, 我叫皮皮鲁\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?'"]},"execution_count":34,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","conversation_zh.predict(input=\"你好, 我叫皮皮鲁\")"]},{"cell_type":"markdown","id":"e71564ad","metadata":{},"source":["### 2.2 第二轮对话"]},{"cell_type":"markdown","id":"54d006bd","metadata":{},"source":["当我们进行下一轮对话时,他会保留上面的提示"]},{"cell_type":"code","execution_count":35,"id":"cc3ef937","metadata":{"height":31},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","Human: Hi, my name is Andrew\n","AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n","Human: What is 1+1?\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'1+1 is equal to 2.'"]},"execution_count":35,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"What is 1+1?\")"]},{"cell_type":"code","execution_count":36,"id":"63efc1bb","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","Human: 你好, 我叫皮皮鲁\n","AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n","Human: 1+1等于多少?\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'1+1等于2。'"]},"execution_count":36,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","conversation_zh.predict(input=\"1+1等于多少?\")"]},{"cell_type":"markdown","id":"33cb734b","metadata":{},"source":["### 2.3 第三轮对话"]},{"cell_type":"markdown","id":"0393df3d","metadata":{},"source":["为了验证他是否记忆了前面的对话内容,我们让他回答前面已经说过的内容(我的名字),可以看到他确实输出了正确的名字,因此这个对话链随着往下进行会越来越长"]},{"cell_type":"code","execution_count":37,"id":"acf3339a","metadata":{"height":31},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","Human: Hi, my name is Andrew\n","AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n","Human: What is 1+1?\n","AI: 1+1 is equal to 2.\n","Human: What is my name?\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'Your name is Andrew.'"]},"execution_count":37,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"What is my name?\")"]},{"cell_type":"code","execution_count":38,"id":"2206e5b7","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new chain...\u001b[0m\n","Prompt after formatting:\n","\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n","\n","Current conversation:\n","Human: 你好, 我叫皮皮鲁\n","AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n","Human: 1+1等于多少?\n","AI: 1+1等于2。\n","Human: 我叫什么名字?\n","AI:\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'你叫皮皮鲁。'"]},"execution_count":38,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","conversation_zh.predict(input=\"我叫什么名字?\")"]},{"cell_type":"markdown","id":"5a96a8d9","metadata":{},"source":["### 2.4 .memory.buffer存储了当前为止所有的对话信息"]},{"cell_type":"code","execution_count":39,"id":"2529400d","metadata":{"height":31},"outputs":[{"name":"stdout","output_type":"stream","text":["Human: Hi, my name is Andrew\n","AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n","Human: What is 1+1?\n","AI: 1+1 is equal to 2.\n","Human: What is my name?\n","AI: Your name is Andrew.\n"]}],"source":["print(memory.buffer) #提取历史消息"]},{"cell_type":"code","execution_count":40,"id":"d948aeb2","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Human: 你好, 我叫皮皮鲁\n","AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n","Human: 1+1等于多少?\n","AI: 1+1等于2。\n","Human: 我叫什么名字?\n","AI: 你叫皮皮鲁。\n"]}],"source":["# 中文\n","print(memory_zh.buffer) #提取历史消息"]},{"cell_type":"markdown","id":"6bd222c3","metadata":{},"source":["### 2.5 也可以通过memory.load_memory_variables({})打印历史消息"]},{"cell_type":"markdown","id":"0b5de846","metadata":{},"source":["这里的花括号实际上是一个空字典,有一些更高级的功能,使用户可以使用更复杂的输入,但我们不会在这个短期课程中讨论它们,所以不要担心为什么这里有一个空的花括号。"]},{"cell_type":"code","execution_count":41,"id":"5018cb0a","metadata":{"height":31},"outputs":[{"data":{"text/plain":["{'history': \"Human: Hi, my name is Andrew\\nAI: Hello Andrew! It's nice to meet you. How can I assist you today?\\nHuman: What is 1+1?\\nAI: 1+1 is equal to 2.\\nHuman: What is my name?\\nAI: Your name is Andrew.\"}"]},"execution_count":41,"metadata":{},"output_type":"execute_result"}],"source":["memory.load_memory_variables({})"]},{"cell_type":"code","execution_count":42,"id":"af4b8b12","metadata":{},"outputs":[{"data":{"text/plain":["{'history': 'Human: 你好, 我叫皮皮鲁\\nAI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\\nHuman: 1+1等于多少?\\nAI: 1+1等于2。\\nHuman: 我叫什么名字?\\nAI: 你叫皮皮鲁。'}"]},"execution_count":42,"metadata":{},"output_type":"execute_result"}],"source":["# 中文\n","memory_zh.load_memory_variables({})"]},{"cell_type":"markdown","id":"07d2e892","metadata":{},"source":["### 2.6 添加指定的输入输出内容到记忆缓存区"]},{"cell_type":"code","execution_count":43,"id":"14219b70","metadata":{"height":31},"outputs":[],"source":["memory = ConversationBufferMemory() #新建一个空的对话缓存记忆"]},{"cell_type":"code","execution_count":45,"id":"a36e9905","metadata":{"height":48},"outputs":[],"source":["memory.save_context({\"input\": \"Hi\"}, #向缓存区添加指定对话的输入输出\n"," {\"output\": \"What's up\"})"]},{"cell_type":"code","execution_count":46,"id":"61631b1f","metadata":{"height":31},"outputs":[{"name":"stdout","output_type":"stream","text":["Human: Hi\n","AI: What's up\n","Human: Hi\n","AI: What's up\n"]}],"source":["print(memory.buffer) #查看缓存区结果"]},{"cell_type":"code","execution_count":47,"id":"a2fdf9ec","metadata":{"height":31},"outputs":[{"data":{"text/plain":["{'history': \"Human: Hi\\nAI: What's up\\nHuman: Hi\\nAI: What's up\"}"]},"execution_count":47,"metadata":{},"output_type":"execute_result"}],"source":["memory.load_memory_variables({}) #再次加载记忆变量"]},{"cell_type":"code","execution_count":48,"id":"27d8dd2f","metadata":{},"outputs":[{"data":{"text/plain":["{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西'}"]},"execution_count":48,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","memory = ConversationBufferMemory()\n","memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, \n"," {\"output\": \"你好啊,我叫鲁西西\"})\n","memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"2ac544f2","metadata":{},"source":["继续添加新的内容,对话历史都保存下来在了!"]},{"cell_type":"code","execution_count":49,"id":"7ca79256","metadata":{"height":64},"outputs":[],"source":["memory.save_context({\"input\": \"Not much, just hanging\"}, \n"," {\"output\": \"Cool\"})"]},{"cell_type":"code","execution_count":50,"id":"890a4497","metadata":{"height":31},"outputs":[{"data":{"text/plain":["{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool'}"]},"execution_count":50,"metadata":{},"output_type":"execute_result"}],"source":["memory.load_memory_variables({})"]},{"cell_type":"code","execution_count":51,"id":"2b614406","metadata":{},"outputs":[{"data":{"text/plain":["{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool\\nHuman: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}"]},"execution_count":51,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, \n"," {\"output\": \"是的,让我们一起去冒险吧!\"})\n","memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"8839314a","metadata":{},"source":["当我们在使用大型语言模型进行聊天对话时,**大型语言模型本身实际上是无状态的。语言模型本身并不记得到目前为止的历史对话**。每次调用API结点都是独立的。\n","\n","聊天机器人似乎有记忆,只是因为通常有快速的代码可以向LLM提供迄今为止的完整对话以及上下文。因此,Memory可以明确地存储到目前为止的所有术语或对话。这个Memory存储器被用作输入或附加上下文到LLM中,以便它可以生成一个输出,就好像它只有在进行下一轮对话的时候,才知道之前说过什么。\n"]},{"cell_type":"markdown","id":"cf98e9ff","metadata":{},"source":["## 三、对话缓存窗口储存\n"," \n","随着对话变得越来越长,所需的内存量也变得非常长。将大量的tokens发送到LLM的成本,也会变得更加昂贵,这也就是为什么API的调用费用,通常是基于它需要处理的tokens数量而收费的。\n"," \n","针对以上问题,LangChain也提供了几种方便的memory来保存历史对话。\n","其中,对话缓存窗口记忆只保留一个窗口大小的对话缓存区窗口记忆。它只使用最近的n次交互。这可以用于保持最近交互的滑动窗口,以便缓冲区不会过大"]},{"cell_type":"code","execution_count":52,"id":"66eeccc3","metadata":{"height":47},"outputs":[],"source":["from langchain.memory import ConversationBufferWindowMemory"]},{"cell_type":"markdown","id":"641477a4","metadata":{},"source":["### 3.1 向memory添加两轮对话,并查看记忆变量当前的记录"]},{"cell_type":"code","execution_count":53,"id":"3ea6233e","metadata":{"height":47},"outputs":[],"source":["memory = ConversationBufferWindowMemory(k=1) # k=1表明只保留一个对话记忆 "]},{"cell_type":"code","execution_count":54,"id":"dc4553fb","metadata":{"height":115},"outputs":[],"source":["memory.save_context({\"input\": \"Hi\"},\n"," {\"output\": \"What's up\"})\n","memory.save_context({\"input\": \"Not much, just hanging\"},\n"," {\"output\": \"Cool\"})\n"]},{"cell_type":"code","execution_count":55,"id":"6a788403","metadata":{"height":31},"outputs":[{"data":{"text/plain":["{'history': 'Human: Not much, just hanging\\nAI: Cool'}"]},"execution_count":55,"metadata":{},"output_type":"execute_result"}],"source":["memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"9b401f0b","metadata":{},"source":["### 3.2 在看一个例子,发现和上面的结果一样,只保留了一轮对话记忆"]},{"cell_type":"code","execution_count":56,"id":"68a2907c","metadata":{},"outputs":[{"data":{"text/plain":["{'history': 'Human: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}"]},"execution_count":56,"metadata":{},"output_type":"execute_result"}],"source":["#中文\n","memory = ConversationBufferWindowMemory(k=1) # k=1表明只保留一个对话记忆 \n","memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, \n"," {\"output\": \"你好啊,我叫鲁西西\"})\n","memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, \n"," {\"output\": \"是的,让我们一起去冒险吧!\"})\n","memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"63bda148","metadata":{},"source":["### 3.3 将对话缓存窗口记忆应用到对话链中"]},{"cell_type":"code","execution_count":57,"id":"4087bc87","metadata":{"height":133},"outputs":[],"source":["llm = ChatOpenAI(temperature=0.0)\n","memory = ConversationBufferWindowMemory(k=1)\n","conversation = ConversationChain( \n"," llm=llm, \n"," memory = memory,\n"," verbose=False #这里改为FALSE不显示提示,你可以尝试修改为TRUE后的结果\n",")"]},{"cell_type":"code","execution_count":61,"id":"0c737101","metadata":{},"outputs":[],"source":["# 中文版\n","llm = ChatOpenAI(temperature=0.0)\n","memory_zh = ConversationBufferWindowMemory(k=1)\n","conversation_zh = ConversationChain( \n"," llm=llm, \n"," memory = memory_zh,\n"," verbose=False #这里改为FALSE不显示提示,你可以尝试修改为TRUE后的结果\n",")"]},{"cell_type":"markdown","id":"b6d661e3","metadata":{},"source":["注意此处!由于这里用的是一个窗口的记忆,因此只能保存一轮的历史消息,因此AI并不能知道你第一轮对话中提到的名字,他最多只能记住上一轮(第二轮)的对话信息"]},{"cell_type":"code","execution_count":58,"id":"4faaa952","metadata":{"height":47},"outputs":[{"data":{"text/plain":["\"Hello Andrew! It's nice to meet you. How can I assist you today?\""]},"execution_count":58,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"Hi, my name is Andrew\")"]},{"cell_type":"code","execution_count":63,"id":"b3a941b5","metadata":{},"outputs":[{"data":{"text/plain":["'你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?'"]},"execution_count":63,"metadata":{},"output_type":"execute_result"}],"source":["conversation_zh.predict(input=\"你好,我是皮皮鲁\")"]},{"cell_type":"code","execution_count":64,"id":"bb20ddaa","metadata":{"height":31},"outputs":[{"data":{"text/plain":["'1+1 is equal to 2.'"]},"execution_count":64,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"What is 1+1?\")"]},{"cell_type":"code","execution_count":65,"id":"90bf6403","metadata":{},"outputs":[{"data":{"text/plain":["'1+1等于2。'"]},"execution_count":65,"metadata":{},"output_type":"execute_result"}],"source":["conversation_zh.predict(input=\"1+1等于几\")"]},{"cell_type":"code","execution_count":66,"id":"489b2194","metadata":{"height":31},"outputs":[{"data":{"text/plain":["\"I'm sorry, but I don't have access to personal information.\""]},"execution_count":66,"metadata":{},"output_type":"execute_result"}],"source":["conversation.predict(input=\"What is my name?\")"]},{"cell_type":"code","execution_count":67,"id":"932ace4f","metadata":{},"outputs":[{"data":{"text/plain":["'很抱歉,我无法知道您的名字。'"]},"execution_count":67,"metadata":{},"output_type":"execute_result"}],"source":["conversation_zh.predict(input=\"我叫什么名字\")"]},{"cell_type":"markdown","id":"d2931b92","metadata":{},"source":["## 四、对话token缓存储存"]},{"cell_type":"markdown","id":"dff5b4c7","metadata":{},"source":["使用对话token缓存记忆,内存将限制保存的token数量。如果token数量超出指定数目,它会切掉这个对话的早期部分\n","以保留与最近的交流相对应的token数量,但不超过token限制。"]},{"cell_type":"code","execution_count":null,"id":"9f6d063c","metadata":{"height":31},"outputs":[],"source":["#!pip install tiktoken #需要用到tiktoken包,没有的可以先安装一下"]},{"cell_type":"markdown","id":"2187cfe6","metadata":{},"source":["### 4.1 导入相关包和API密钥"]},{"cell_type":"code","execution_count":68,"id":"fb9020ed","metadata":{"height":81},"outputs":[],"source":["from langchain.memory import ConversationTokenBufferMemory\n","from langchain.llms import OpenAI\n","\n","llm = ChatOpenAI(temperature=0.0)"]},{"cell_type":"markdown","id":"f3a84112","metadata":{},"source":["### 4.2 限制token数量,进行测试"]},{"cell_type":"code","execution_count":69,"id":"43582ee6","metadata":{"height":149},"outputs":[],"source":["memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n","memory.save_context({\"input\": \"AI is what?!\"},\n"," {\"output\": \"Amazing!\"})\n","memory.save_context({\"input\": \"Backpropagation is what?\"},\n"," {\"output\": \"Beautiful!\"})\n","memory.save_context({\"input\": \"Chatbots are what?\"}, \n"," {\"output\": \"Charming!\"})"]},{"cell_type":"markdown","id":"7b62b2e1","metadata":{},"source":["可以看到前面超出的的token已经被舍弃了!!!"]},{"cell_type":"code","execution_count":70,"id":"284288e1","metadata":{"height":31},"outputs":[{"data":{"text/plain":["{'history': 'AI: Beautiful!\\nHuman: Chatbots are what?\\nAI: Charming!'}"]},"execution_count":70,"metadata":{},"output_type":"execute_result"}],"source":["memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"f7f6be43","metadata":{},"source":["### 4.3 中文例子"]},{"cell_type":"code","execution_count":71,"id":"e9191020","metadata":{},"outputs":[{"data":{"text/plain":["{'history': 'AI: 轻舟已过万重山。'}"]},"execution_count":71,"metadata":{},"output_type":"execute_result"}],"source":["memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n","memory.save_context({\"input\": \"朝辞白帝彩云间,\"}, \n"," {\"output\": \"千里江陵一日还。\"})\n","memory.save_context({\"input\": \"两岸猿声啼不住,\"},\n"," {\"output\": \"轻舟已过万重山。\"})\n","memory.load_memory_variables({})"]},{"cell_type":"markdown","id":"5e4d918b","metadata":{},"source":["补充: \n","\n","ChatGPT使用一种基于字节对编码(Byte Pair Encoding,BPE)的方法来进行tokenization(将输入文本拆分为token)。 \n","BPE是一种常见的tokenization技术,它将输入文本分割成较小的子词单元。 \n","\n","OpenAI在其官方GitHub上公开了一个最新的开源Python库:tiktoken,这个库主要是用来计算tokens数量的。相比较Hugging Face的tokenizer,其速度提升了好几倍\n", " OPENAI_API_KEY=\"your_api_key\" \n", "
\n", " \n", " \u66ff\u6362\"your_api_key\"\u4e3a\u4f60\u81ea\u5df1\u7684 API Key"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["# \u4e0b\u8f7d\u9700\u8981\u7684\u5305python-dotenv\u548copenai\n", "# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "!pip install -q python-dotenv\n", "!pip install -q openai"]}, {"cell_type": "code", "execution_count": 2, "metadata": {"tags": []}, "outputs": [], "source": ["import os\n", "import openai\n", "from dotenv import load_dotenv, find_dotenv\n", "\n", "# \u8bfb\u53d6\u672c\u5730/\u9879\u76ee\u7684\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "# find_dotenv()\u5bfb\u627e\u5e76\u5b9a\u4f4d.env\u6587\u4ef6\u7684\u8def\u5f84\n", "# load_dotenv()\u8bfb\u53d6\u8be5.env\u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u5230\u5f53\u524d\u7684\u8fd0\u884c\u73af\u5883\u4e2d \n", "# \u5982\u679c\u4f60\u8bbe\u7f6e\u7684\u662f\u5168\u5c40\u7684\u73af\u5883\u53d8\u91cf\uff0c\u8fd9\u884c\u4ee3\u7801\u5219\u6ca1\u6709\u4efb\u4f55\u4f5c\u7528\u3002\n", "_ = load_dotenv(find_dotenv())\n", "\n", "# \u83b7\u53d6\u73af\u5883\u53d8\u91cf OPENAI_API_KEY\n", "openai.api_key = os.environ['OPENAI_API_KEY'] "]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["## \u4e8c\u3001\u76f4\u63a5\u4f7f\u7528OpenAI\n", "\n", "\u6211\u4eec\u5148\u4ece\u76f4\u63a5\u8c03\u7528OpenAI\u7684API\u5f00\u59cb\u3002\n", "\n", "`get_completion`\u51fd\u6570\u662f\u57fa\u4e8e`openai`\u7684\u5c01\u88c5\u51fd\u6570\uff0c\u5bf9\u4e8e\u7ed9\u5b9a\u63d0\u793a\uff08prompt\uff09\u8f93\u51fa\u76f8\u5e94\u7684\u56de\u7b54\u3002\u5176\u5305\u542b\u4e24\u4e2a\u53c2\u6570\n", " \n", " - `prompt` \u5fc5\u9700\u8f93\u5165\u53c2\u6570\u3002 \u4f60\u7ed9\u6a21\u578b\u7684**\u63d0\u793a\uff0c\u53ef\u4ee5\u662f\u4e00\u4e2a\u95ee\u9898\uff0c\u53ef\u4ee5\u662f\u4f60\u9700\u8981\u6a21\u578b\u5e2e\u52a9\u4f60\u505a\u7684\u4e8b**\uff08\u6539\u53d8\u6587\u672c\u5199\u4f5c\u98ce\u683c\uff0c\u7ffb\u8bd1\uff0c\u56de\u590d\u6d88\u606f\u7b49\u7b49\uff09\u3002\n", " - `model` \u975e\u5fc5\u9700\u8f93\u5165\u53c2\u6570\u3002\u9ed8\u8ba4\u4f7f\u7528gpt-3.5-turbo\u3002\u4f60\u4e5f\u53ef\u4ee5\u9009\u62e9\u5176\u4ed6\u6a21\u578b\u3002\n", " \n", "\u8fd9\u91cc\u7684\u63d0\u793a\u5bf9\u5e94\u6211\u4eec\u7ed9chatgpt\u7684\u95ee\u9898\uff0c\u51fd\u6570\u7ed9\u51fa\u7684\u8f93\u51fa\u5219\u5bf9\u5e94chatpgt\u7ed9\u6211\u4eec\u7684\u7b54\u6848\u3002"]}, {"cell_type": "code", "execution_count": 3, "metadata": {"tags": []}, "outputs": [], "source": ["def get_completion(prompt, model=\"gpt-3.5-turbo\"):\n", " \n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " \n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=0, \n", " )\n", " return response.choices[0].message[\"content\"]"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.1 \u8ba1\u7b971+1\n", "\n", "\u6211\u4eec\u6765\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50 - \u5206\u522b\u7528\u4e2d\u82f1\u6587\u95ee\u95ee\u6a21\u578b\n", "\n", "- \u4e2d\u6587\u63d0\u793a(Prompt in Chinese)\uff1a `1+1\u662f\u4ec0\u4e48\uff1f`\n", "- \u82f1\u6587\u63d0\u793a(Prompt in English)\uff1a `What is 1+1?`"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["'1+1\u7b49\u4e8e2\u3002'"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u4e2d\u6587\n", "get_completion(\"1+1\u662f\u4ec0\u4e48\uff1f\")"]}, {"cell_type": "code", "execution_count": 5, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["'1+1 equals 2.'"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u82f1\u6587\n", "get_completion(\"What is 1+1?\")"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.2 \u7528\u7f8e\u5f0f\u82f1\u8bed\u8868\u8fbe\u6d77\u76d7\u90ae\u4ef6\n", "\n", "\u4e0a\u9762\u7684\u7b80\u5355\u4f8b\u5b50\uff0c\u6a21\u578b`gpt-3.5-turbo`\u5bf9\u6211\u4eec\u7684\u5173\u4e8e1+1\u662f\u4ec0\u4e48\u7684\u63d0\u95ee\u7ed9\u51fa\u4e86\u56de\u7b54\u3002\n", "\n", "\u73b0\u5728\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u590d\u6742\u4e00\u70b9\u7684\u4f8b\u5b50\uff1a \n", "\n", "\u5047\u8bbe\u6211\u4eec\u662f\u7535\u5546\u516c\u53f8\u5458\u5de5\uff0c\u6211\u4eec\u7684\u987e\u5ba2\u662f\u4e00\u540d\u6d77\u76d7A\uff0c\u4ed6\u5728\u6211\u4eec\u7684\u7f51\u7ad9\u4e0a\u4e70\u4e86\u4e00\u4e2a\u69a8\u6c41\u673a\u7528\u6765\u505a\u5976\u6614\uff0c\u5728\u5236\u4f5c\u5976\u6614\u7684\u8fc7\u7a0b\u4e2d\uff0c\u5976\u6614\u7684\u76d6\u5b50\u98de\u4e86\u51fa\u53bb\uff0c\u5f04\u5f97\u53a8\u623f\u5899\u4e0a\u5230\u5904\u90fd\u662f\u3002\u4e8e\u662f\u6d77\u76d7A\u7ed9\u6211\u4eec\u7684\u5ba2\u670d\u4e2d\u5fc3\u5199\u6765\u4ee5\u4e0b\u90ae\u4ef6\uff1a`customer_email`"]}, {"cell_type": "code", "execution_count": 6, "metadata": {"tags": []}, "outputs": [], "source": ["customer_email = \"\"\"\n", "Arrr, I be fuming that me blender lid \\\n", "flew off and splattered me kitchen walls \\\n", "with smoothie! And to make matters worse,\\\n", "the warranty don't cover the cost of \\\n", "cleaning up me kitchen. I need yer help \\\n", "right now, matey!\n", "\"\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u6211\u4eec\u7684\u5ba2\u670d\u4eba\u5458\u5bf9\u4e8e\u6d77\u76d7\u7684\u63aa\u8f9e\u8868\u8fbe\u89c9\u5f97\u6709\u70b9\u96be\u4ee5\u7406\u89e3\u3002 \u73b0\u5728\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\u4e24\u4e2a\u5c0f\u76ee\u6807\uff1a\n", "\n", "- \u8ba9\u6a21\u578b\u7528\u7f8e\u5f0f\u82f1\u8bed\u7684\u8868\u8fbe\u65b9\u5f0f\u5c06\u6d77\u76d7\u7684\u90ae\u4ef6\u8fdb\u884c\u7ffb\u8bd1\uff0c\u5ba2\u670d\u4eba\u5458\u53ef\u4ee5\u66f4\u597d\u7406\u89e3\u3002*\u8fd9\u91cc\u6d77\u76d7\u7684\u82f1\u6587\u8868\u8fbe\u53ef\u4ee5\u7406\u89e3\u4e3a\u82f1\u6587\u7684\u65b9\u8a00\uff0c\u5176\u4e0e\u7f8e\u5f0f\u82f1\u8bed\u7684\u5173\u7cfb\uff0c\u5c31\u5982\u56db\u5ddd\u8bdd\u4e0e\u666e\u901a\u8bdd\u7684\u5173\u7cfb\u3002\n", "- \u8ba9\u6a21\u578b\u5728\u7ffb\u8bd1\u662f\u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\u8fdb\u884c\u8868\u8fbe\uff0c\u5ba2\u670d\u4eba\u5458\u7684\u5fc3\u60c5\u4e5f\u4f1a\u66f4\u597d\u3002\n", "\n", "\u6839\u636e\u8fd9\u4e24\u4e2a\u5c0f\u76ee\u6807\uff0c\u5b9a\u4e49\u4e00\u4e0b\u6587\u672c\u8868\u8fbe\u98ce\u683c\uff1a`style`"]}, {"cell_type": "code", "execution_count": 7, "metadata": {"tags": []}, "outputs": [], "source": ["# \u7f8e\u5f0f\u82f1\u8bed + \u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "style = \"\"\"American English \\\n", "in a calm and respectful tone\n", "\"\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u4e0b\u4e00\u6b65\u9700\u8981\u505a\u7684\u662f\u5c06`customer_email`\u548c`style`\u7ed3\u5408\u8d77\u6765\u6784\u9020\u6211\u4eec\u7684\u63d0\u793a:`prompt`"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": ["# \u975e\u6b63\u5f0f\u7528\u8bed\n", "customer_email = \"\"\" \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\\\n", "\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\\\n", "\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\\\n", "\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\\\n", "\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "\"\"\""]}, {"cell_type": "code", "execution_count": 9, "metadata": {"tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Translate the text that is delimited by triple backticks \n", "into a style that is American English in a calm and respectful tone\n", ".\n", "text: ``` \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "```\n", "\n"]}], "source": ["# \u8981\u6c42\u6a21\u578b\u6839\u636e\u7ed9\u51fa\u7684\u8bed\u8c03\u8fdb\u884c\u8f6c\u5316\n", "prompt = f\"\"\"Translate the text \\\n", "that is delimited by triple backticks \n", "into a style that is {style}.\n", "text: ```{customer_email}```\n", "\"\"\"\n", "\n", "print(prompt)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`prompt` \u6784\u9020\u597d\u4e86\uff0c\u6211\u4eec\u53ef\u4ee5\u8c03\u7528`get_completion`\u5f97\u5230\u6211\u4eec\u60f3\u8981\u7684\u7ed3\u679c - \u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\uff0c\u7f8e\u5f0f\u82f1\u8bed\u8868\u8fbe\u7684\u6d77\u76d7\u8bed\u8a00\u90ae\u4ef6"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": ["response = get_completion(prompt)"]}, {"cell_type": "code", "execution_count": 11, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["\"Oh, I'm really frustrated because the lid of my blender fell off and splattered the milkshake all over the kitchen wall! To make matters worse, the warranty doesn't cover the cost of cleaning the kitchen. I could really use your help right now, buddy!\""]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["response"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u5bf9\u6bd4\u8bed\u8a00\u98ce\u683c\u8f6c\u6362\u524d\u540e\uff0c\u7528\u8bcd\u66f4\u4e3a\u6b63\u5f0f\uff0c\u66ff\u6362\u4e86\u6781\u7aef\u60c5\u7eea\u7684\u8868\u8fbe\uff0c\u5e76\u8868\u8fbe\u4e86\u611f\u8c22\u3002\n", "\n", "\u2728 \u4f60\u53ef\u4ee5\u5c1d\u8bd5\u4fee\u6539\u63d0\u793a\uff0c\u770b\u53ef\u4ee5\u5f97\u5230\u4ec0\u4e48\u4e0d\u4e00\u6837\u7684\u7ed3\u679c\ud83d\ude09"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.3 \u4e2d\u6587\u7248"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": ["# \u666e\u901a\u8bdd + \u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "style = \"\"\"\u6b63\u5f0f\u666e\u901a\u8bdd \\\n", "\u7528\u4e00\u4e2a\u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "\"\"\""]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u628a\u7531\u4e09\u4e2a\u53cd\u5f15\u53f7\u5206\u9694\u7684\u6587\u672c\u7ffb\u8bd1\u6210\u4e00\u79cd\u6b63\u5f0f\u666e\u901a\u8bdd \u7528\u4e00\u4e2a\u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "\u98ce\u683c\u3002\n", "\u6587\u672c: ``` \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "```\n", "\n"]}], "source": ["# \u8981\u6c42\u6a21\u578b\u6839\u636e\u7ed9\u51fa\u7684\u8bed\u8c03\u8fdb\u884c\u8f6c\u5316\n", "prompt = f\"\"\"\u628a\u7531\u4e09\u4e2a\u53cd\u5f15\u53f7\u5206\u9694\u7684\u6587\u672c\\\n", "\u7ffb\u8bd1\u6210\u4e00\u79cd{style}\u98ce\u683c\u3002\n", "\u6587\u672c: ```{customer_email}```\n", "\"\"\"\n", "\n", "print(prompt)\n", "\n"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["'\u5c0a\u656c\u7684\u670b\u53cb\u4eec\uff0c\u6211\u611f\u5230\u975e\u5e38\u4e0d\u5b89\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u5b50\u4e0d\u614e\u6389\u843d\uff0c\u5bfc\u81f4\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u58c1\u4e0a\uff01\u66f4\u52a0\u4ee4\u4eba\u7cdf\u5fc3\u7684\u662f\uff0c\u4fdd\u4fee\u670d\u52a1\u5e76\u4e0d\u5305\u542b\u53a8\u623f\u6e05\u6d01\u7684\u8d39\u7528\u3002\u6b64\u523b\uff0c\u6211\u771f\u8bda\u5730\u8bf7\u6c42\u5404\u4f4d\u7684\u5e2e\u52a9\uff0c\u670b\u53cb\u4eec\uff01'"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["response = get_completion(prompt)\n", "\n", "response"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["## \u4e09\u3001\u901a\u8fc7LangChain\u4f7f\u7528OpenAI\n", "\n", "\u5728\u524d\u9762\u4e00\u90e8\u5206\uff0c\u6211\u4eec\u901a\u8fc7\u5c01\u88c5\u51fd\u6570`get_completion`\u76f4\u63a5\u8c03\u7528\u4e86OpenAI\u5b8c\u6210\u4e86\u5bf9\u65b9\u8a00\u90ae\u4ef6\u8fdb\u884c\u4e86\u7684\u7ffb\u8bd1\uff0c\u5f97\u5230\u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\u3001\u6b63\u5f0f\u7684\u666e\u901a\u8bdd\u8868\u8fbe\u7684\u90ae\u4ef6\u3002\n", "\n", "\u8ba9\u6211\u4eec\u5c1d\u8bd5\u4f7f\u7528LangChain\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u529f\u80fd\u3002"]}, {"cell_type": "code", "execution_count": 15, "metadata": {"tags": []}, "outputs": [], "source": ["# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "# --upgrade \u8ba9\u6211\u4eec\u53ef\u4ee5\u5b89\u88c5\u5230\u6700\u65b0\u7248\u672c\u7684 langchain\n", "!pip install -q --upgrade langchain"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 3.1 \u6a21\u578b\n", "\n", "\u4ece`langchain.chat_models`\u5bfc\u5165`OpenAI`\u7684\u5bf9\u8bdd\u6a21\u578b`ChatOpenAI`\u3002 \u9664\u53bbOpenAI\u4ee5\u5916\uff0c`langchain.chat_models`\u8fd8\u96c6\u6210\u4e86\u5176\u4ed6\u5bf9\u8bdd\u6a21\u578b\uff0c\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u67e5\u770b[Langchain\u5b98\u65b9\u6587\u6863](https://python.langchain.com/en/latest/modules/models/chat/integrations.html)\u3002"]}, {"cell_type": "code", "execution_count": 16, "metadata": {"tags": []}, "outputs": [], "source": ["from langchain.chat_models import ChatOpenAI"]}, {"cell_type": "code", "execution_count": 17, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, metadata=None, client=\n", " OPENAI_API_KEY=\"your_api_key\" \n", "
\n", " \n", " \u66ff\u6362\"your_api_key\"\u4e3a\u4f60\u81ea\u5df1\u7684 API Key"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["# \u4e0b\u8f7d\u9700\u8981\u7684\u5305python-dotenv\u548copenai\n", "# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "!pip install -q python-dotenv\n", "!pip install -q openai"]}, {"cell_type": "code", "execution_count": 2, "metadata": {"tags": []}, "outputs": [], "source": ["import os\n", "import openai\n", "from dotenv import load_dotenv, find_dotenv\n", "\n", "# \u8bfb\u53d6\u672c\u5730/\u9879\u76ee\u7684\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "# find_dotenv()\u5bfb\u627e\u5e76\u5b9a\u4f4d.env\u6587\u4ef6\u7684\u8def\u5f84\n", "# load_dotenv()\u8bfb\u53d6\u8be5.env\u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u5230\u5f53\u524d\u7684\u8fd0\u884c\u73af\u5883\u4e2d \n", "# \u5982\u679c\u4f60\u8bbe\u7f6e\u7684\u662f\u5168\u5c40\u7684\u73af\u5883\u53d8\u91cf\uff0c\u8fd9\u884c\u4ee3\u7801\u5219\u6ca1\u6709\u4efb\u4f55\u4f5c\u7528\u3002\n", "_ = load_dotenv(find_dotenv())\n", "\n", "# \u83b7\u53d6\u73af\u5883\u53d8\u91cf OPENAI_API_KEY\n", "openai.api_key = os.environ['OPENAI_API_KEY'] "]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["## \u4e8c\u3001\u76f4\u63a5\u4f7f\u7528OpenAI\n", "\n", "\u6211\u4eec\u5148\u4ece\u76f4\u63a5\u8c03\u7528OpenAI\u7684API\u5f00\u59cb\u3002\n", "\n", "`get_completion`\u51fd\u6570\u662f\u57fa\u4e8e`openai`\u7684\u5c01\u88c5\u51fd\u6570\uff0c\u5bf9\u4e8e\u7ed9\u5b9a\u63d0\u793a\uff08prompt\uff09\u8f93\u51fa\u76f8\u5e94\u7684\u56de\u7b54\u3002\u5176\u5305\u542b\u4e24\u4e2a\u53c2\u6570\n", " \n", " - `prompt` \u5fc5\u9700\u8f93\u5165\u53c2\u6570\u3002 \u4f60\u7ed9\u6a21\u578b\u7684**\u63d0\u793a\uff0c\u53ef\u4ee5\u662f\u4e00\u4e2a\u95ee\u9898\uff0c\u53ef\u4ee5\u662f\u4f60\u9700\u8981\u6a21\u578b\u5e2e\u52a9\u4f60\u505a\u7684\u4e8b**\uff08\u6539\u53d8\u6587\u672c\u5199\u4f5c\u98ce\u683c\uff0c\u7ffb\u8bd1\uff0c\u56de\u590d\u6d88\u606f\u7b49\u7b49\uff09\u3002\n", " - `model` \u975e\u5fc5\u9700\u8f93\u5165\u53c2\u6570\u3002\u9ed8\u8ba4\u4f7f\u7528gpt-3.5-turbo\u3002\u4f60\u4e5f\u53ef\u4ee5\u9009\u62e9\u5176\u4ed6\u6a21\u578b\u3002\n", " \n", "\u8fd9\u91cc\u7684\u63d0\u793a\u5bf9\u5e94\u6211\u4eec\u7ed9chatgpt\u7684\u95ee\u9898\uff0c\u51fd\u6570\u7ed9\u51fa\u7684\u8f93\u51fa\u5219\u5bf9\u5e94chatpgt\u7ed9\u6211\u4eec\u7684\u7b54\u6848\u3002"]}, {"cell_type": "code", "execution_count": 3, "metadata": {"tags": []}, "outputs": [], "source": ["def get_completion(prompt, model=\"gpt-3.5-turbo\"):\n", " \n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " \n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=0, \n", " )\n", " return response.choices[0].message[\"content\"]"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.1 \u8ba1\u7b971+1\n", "\n", "\u6211\u4eec\u6765\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50 - \u5206\u522b\u7528\u4e2d\u82f1\u6587\u95ee\u95ee\u6a21\u578b\n", "\n", "- \u4e2d\u6587\u63d0\u793a(Prompt in Chinese)\uff1a `1+1\u662f\u4ec0\u4e48\uff1f`\n", "- \u82f1\u6587\u63d0\u793a(Prompt in English)\uff1a `What is 1+1?`"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["'1+1\u7b49\u4e8e2\u3002'"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u4e2d\u6587\n", "get_completion(\"1+1\u662f\u4ec0\u4e48\uff1f\")"]}, {"cell_type": "code", "execution_count": 5, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["'1+1 equals 2.'"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u82f1\u6587\n", "get_completion(\"What is 1+1?\")"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.2 \u7528\u7f8e\u5f0f\u82f1\u8bed\u8868\u8fbe\u6d77\u76d7\u90ae\u4ef6\n", "\n", "\u4e0a\u9762\u7684\u7b80\u5355\u4f8b\u5b50\uff0c\u6a21\u578b`gpt-3.5-turbo`\u5bf9\u6211\u4eec\u7684\u5173\u4e8e1+1\u662f\u4ec0\u4e48\u7684\u63d0\u95ee\u7ed9\u51fa\u4e86\u56de\u7b54\u3002\n", "\n", "\u73b0\u5728\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u590d\u6742\u4e00\u70b9\u7684\u4f8b\u5b50\uff1a \n", "\n", "\u5047\u8bbe\u6211\u4eec\u662f\u7535\u5546\u516c\u53f8\u5458\u5de5\uff0c\u6211\u4eec\u7684\u987e\u5ba2\u662f\u4e00\u540d\u6d77\u76d7A\uff0c\u4ed6\u5728\u6211\u4eec\u7684\u7f51\u7ad9\u4e0a\u4e70\u4e86\u4e00\u4e2a\u69a8\u6c41\u673a\u7528\u6765\u505a\u5976\u6614\uff0c\u5728\u5236\u4f5c\u5976\u6614\u7684\u8fc7\u7a0b\u4e2d\uff0c\u5976\u6614\u7684\u76d6\u5b50\u98de\u4e86\u51fa\u53bb\uff0c\u5f04\u5f97\u53a8\u623f\u5899\u4e0a\u5230\u5904\u90fd\u662f\u3002\u4e8e\u662f\u6d77\u76d7A\u7ed9\u6211\u4eec\u7684\u5ba2\u670d\u4e2d\u5fc3\u5199\u6765\u4ee5\u4e0b\u90ae\u4ef6\uff1a`customer_email`"]}, {"cell_type": "code", "execution_count": 6, "metadata": {"tags": []}, "outputs": [], "source": ["customer_email = \"\"\"\n", "Arrr, I be fuming that me blender lid \\\n", "flew off and splattered me kitchen walls \\\n", "with smoothie! And to make matters worse,\\\n", "the warranty don't cover the cost of \\\n", "cleaning up me kitchen. I need yer help \\\n", "right now, matey!\n", "\"\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u6211\u4eec\u7684\u5ba2\u670d\u4eba\u5458\u5bf9\u4e8e\u6d77\u76d7\u7684\u63aa\u8f9e\u8868\u8fbe\u89c9\u5f97\u6709\u70b9\u96be\u4ee5\u7406\u89e3\u3002 \u73b0\u5728\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\u4e24\u4e2a\u5c0f\u76ee\u6807\uff1a\n", "\n", "- \u8ba9\u6a21\u578b\u7528\u7f8e\u5f0f\u82f1\u8bed\u7684\u8868\u8fbe\u65b9\u5f0f\u5c06\u6d77\u76d7\u7684\u90ae\u4ef6\u8fdb\u884c\u7ffb\u8bd1\uff0c\u5ba2\u670d\u4eba\u5458\u53ef\u4ee5\u66f4\u597d\u7406\u89e3\u3002*\u8fd9\u91cc\u6d77\u76d7\u7684\u82f1\u6587\u8868\u8fbe\u53ef\u4ee5\u7406\u89e3\u4e3a\u82f1\u6587\u7684\u65b9\u8a00\uff0c\u5176\u4e0e\u7f8e\u5f0f\u82f1\u8bed\u7684\u5173\u7cfb\uff0c\u5c31\u5982\u56db\u5ddd\u8bdd\u4e0e\u666e\u901a\u8bdd\u7684\u5173\u7cfb\u3002\n", "- \u8ba9\u6a21\u578b\u5728\u7ffb\u8bd1\u662f\u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\u8fdb\u884c\u8868\u8fbe\uff0c\u5ba2\u670d\u4eba\u5458\u7684\u5fc3\u60c5\u4e5f\u4f1a\u66f4\u597d\u3002\n", "\n", "\u6839\u636e\u8fd9\u4e24\u4e2a\u5c0f\u76ee\u6807\uff0c\u5b9a\u4e49\u4e00\u4e0b\u6587\u672c\u8868\u8fbe\u98ce\u683c\uff1a`style`"]}, {"cell_type": "code", "execution_count": 7, "metadata": {"tags": []}, "outputs": [], "source": ["# \u7f8e\u5f0f\u82f1\u8bed + \u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "style = \"\"\"American English \\\n", "in a calm and respectful tone\n", "\"\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u4e0b\u4e00\u6b65\u9700\u8981\u505a\u7684\u662f\u5c06`customer_email`\u548c`style`\u7ed3\u5408\u8d77\u6765\u6784\u9020\u6211\u4eec\u7684\u63d0\u793a:`prompt`"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": ["# \u975e\u6b63\u5f0f\u7528\u8bed\n", "customer_email = \"\"\" \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\\\n", "\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\\\n", "\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\\\n", "\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\\\n", "\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "\"\"\""]}, {"cell_type": "code", "execution_count": 9, "metadata": {"tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Translate the text that is delimited by triple backticks \n", "into a style that is American English in a calm and respectful tone\n", ".\n", "text: ``` \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "```\n", "\n"]}], "source": ["# \u8981\u6c42\u6a21\u578b\u6839\u636e\u7ed9\u51fa\u7684\u8bed\u8c03\u8fdb\u884c\u8f6c\u5316\n", "prompt = f\"\"\"Translate the text \\\n", "that is delimited by triple backticks \n", "into a style that is {style}.\n", "text: ```{customer_email}```\n", "\"\"\"\n", "\n", "print(prompt)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`prompt` \u6784\u9020\u597d\u4e86\uff0c\u6211\u4eec\u53ef\u4ee5\u8c03\u7528`get_completion`\u5f97\u5230\u6211\u4eec\u60f3\u8981\u7684\u7ed3\u679c - \u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\uff0c\u7f8e\u5f0f\u82f1\u8bed\u8868\u8fbe\u7684\u6d77\u76d7\u8bed\u8a00\u90ae\u4ef6"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": ["response = get_completion(prompt)"]}, {"cell_type": "code", "execution_count": 11, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["\"Oh, I'm really frustrated because the lid of my blender fell off and splattered the milkshake all over the kitchen wall! To make matters worse, the warranty doesn't cover the cost of cleaning the kitchen. I could really use your help right now, buddy!\""]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["response"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\u5bf9\u6bd4\u8bed\u8a00\u98ce\u683c\u8f6c\u6362\u524d\u540e\uff0c\u7528\u8bcd\u66f4\u4e3a\u6b63\u5f0f\uff0c\u66ff\u6362\u4e86\u6781\u7aef\u60c5\u7eea\u7684\u8868\u8fbe\uff0c\u5e76\u8868\u8fbe\u4e86\u611f\u8c22\u3002\n", "\n", "\u2728 \u4f60\u53ef\u4ee5\u5c1d\u8bd5\u4fee\u6539\u63d0\u793a\uff0c\u770b\u53ef\u4ee5\u5f97\u5230\u4ec0\u4e48\u4e0d\u4e00\u6837\u7684\u7ed3\u679c\ud83d\ude09"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 2.3 \u4e2d\u6587\u7248"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": ["# \u666e\u901a\u8bdd + \u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "style = \"\"\"\u6b63\u5f0f\u666e\u901a\u8bdd \\\n", "\u7528\u4e00\u4e2a\u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "\"\"\""]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u628a\u7531\u4e09\u4e2a\u53cd\u5f15\u53f7\u5206\u9694\u7684\u6587\u672c\u7ffb\u8bd1\u6210\u4e00\u79cd\u6b63\u5f0f\u666e\u901a\u8bdd \u7528\u4e00\u4e2a\u5e73\u9759\u3001\u5c0a\u656c\u7684\u8bed\u8c03\n", "\u98ce\u683c\u3002\n", "\u6587\u672c: ``` \n", "\u963f\uff0c\u6211\u5f88\u751f\u6c14\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u6389\u4e86\uff0c\u628a\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u4e0a\uff01\u66f4\u7cdf\u7cd5\u7684\u662f\uff0c\u4fdd\u4fee\u4e0d\u5305\u62ec\u6253\u626b\u53a8\u623f\u7684\u8d39\u7528\u3002\u6211\u73b0\u5728\u9700\u8981\u4f60\u7684\u5e2e\u52a9\uff0c\u4f19\u8ba1\uff01\n", "```\n", "\n"]}], "source": ["# \u8981\u6c42\u6a21\u578b\u6839\u636e\u7ed9\u51fa\u7684\u8bed\u8c03\u8fdb\u884c\u8f6c\u5316\n", "prompt = f\"\"\"\u628a\u7531\u4e09\u4e2a\u53cd\u5f15\u53f7\u5206\u9694\u7684\u6587\u672c\\\n", "\u7ffb\u8bd1\u6210\u4e00\u79cd{style}\u98ce\u683c\u3002\n", "\u6587\u672c: ```{customer_email}```\n", "\"\"\"\n", "\n", "print(prompt)\n", "\n"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["'\u5c0a\u656c\u7684\u670b\u53cb\u4eec\uff0c\u6211\u611f\u5230\u975e\u5e38\u4e0d\u5b89\uff0c\u56e0\u4e3a\u6211\u7684\u6405\u62cc\u673a\u76d6\u5b50\u4e0d\u614e\u6389\u843d\uff0c\u5bfc\u81f4\u5976\u6614\u6e85\u5230\u4e86\u53a8\u623f\u7684\u5899\u58c1\u4e0a\uff01\u66f4\u52a0\u4ee4\u4eba\u7cdf\u5fc3\u7684\u662f\uff0c\u4fdd\u4fee\u670d\u52a1\u5e76\u4e0d\u5305\u542b\u53a8\u623f\u6e05\u6d01\u7684\u8d39\u7528\u3002\u6b64\u523b\uff0c\u6211\u771f\u8bda\u5730\u8bf7\u6c42\u5404\u4f4d\u7684\u5e2e\u52a9\uff0c\u670b\u53cb\u4eec\uff01'"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["response = get_completion(prompt)\n", "\n", "response"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["## \u4e09\u3001\u901a\u8fc7LangChain\u4f7f\u7528OpenAI\n", "\n", "\u5728\u524d\u9762\u4e00\u90e8\u5206\uff0c\u6211\u4eec\u901a\u8fc7\u5c01\u88c5\u51fd\u6570`get_completion`\u76f4\u63a5\u8c03\u7528\u4e86OpenAI\u5b8c\u6210\u4e86\u5bf9\u65b9\u8a00\u90ae\u4ef6\u8fdb\u884c\u4e86\u7684\u7ffb\u8bd1\uff0c\u5f97\u5230\u7528\u5e73\u548c\u5c0a\u91cd\u7684\u8bed\u6c14\u3001\u6b63\u5f0f\u7684\u666e\u901a\u8bdd\u8868\u8fbe\u7684\u90ae\u4ef6\u3002\n", "\n", "\u8ba9\u6211\u4eec\u5c1d\u8bd5\u4f7f\u7528LangChain\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u529f\u80fd\u3002"]}, {"cell_type": "code", "execution_count": 15, "metadata": {"tags": []}, "outputs": [], "source": ["# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "# --upgrade \u8ba9\u6211\u4eec\u53ef\u4ee5\u5b89\u88c5\u5230\u6700\u65b0\u7248\u672c\u7684 langchain\n", "!pip install -q --upgrade langchain"]}, {"cell_type": "markdown", "metadata": {"tags": []}, "source": ["### 3.1 \u6a21\u578b\n", "\n", "\u4ece`langchain.chat_models`\u5bfc\u5165`OpenAI`\u7684\u5bf9\u8bdd\u6a21\u578b`ChatOpenAI`\u3002 \u9664\u53bbOpenAI\u4ee5\u5916\uff0c`langchain.chat_models`\u8fd8\u96c6\u6210\u4e86\u5176\u4ed6\u5bf9\u8bdd\u6a21\u578b\uff0c\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u67e5\u770b[Langchain\u5b98\u65b9\u6587\u6863](https://python.langchain.com/en/latest/modules/models/chat/integrations.html)\u3002"]}, {"cell_type": "code", "execution_count": 16, "metadata": {"tags": []}, "outputs": [], "source": ["from langchain.chat_models import ChatOpenAI"]}, {"cell_type": "code", "execution_count": 17, "metadata": {"tags": []}, "outputs": [{"data": {"text/plain": ["ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, metadata=None, client=\n", - " OPENAI_API_KEY=\"your_api_key\" \n", - "
\n", - " \n", - " 替换\"your_api_key\"为你自己的 API Key" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6932bd47-c6d5-4794-8102-a12b84412a93", - "metadata": {}, - "outputs": [], - "source": [ - "# 下载需要的包python-dotenv和openai\n", - "# 如果你需要查看安装过程日志,可删除 -q\n", - "!pip install -q python-dotenv\n", - "!pip install -q openai" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "10446712-9fa6-4d71-94ce-2ea4cf197e54", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "import openai\n", - "from dotenv import find_dotenv, load_dotenv\n", - "\n", - "# 读取本地/项目的环境变量。\n", - "\n", - "# find_dotenv()寻找并定位.env文件的路径\n", - "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中\n", - "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", - "_ = load_dotenv(find_dotenv())\n", - "\n", - "# 获取环境变量 OPENAI_API_KEY\n", - "openai.api_key = os.environ[\"OPENAI_API_KEY\"]" - ] - }, - { - "cell_type": "markdown", - "id": "1297dcd5", - "metadata": { - "tags": [] - }, - "source": [ - "## 二、对话缓存储存\n", - " " - ] - }, - { - "cell_type": "markdown", - "id": "ffa8cd26-45c5-4bae-90b2-b07d23bf3bb2", - "metadata": {}, - "source": [ - "### 2.1 英文版" - ] - }, - { - "cell_type": "markdown", - "id": "b7e77a3d-7aaa-48c1-b219-19bd6f4eb674", - "metadata": { - "tags": [] - }, - "source": [ - "#### 2.1.1 初始化对话模型" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "20ad6fe2", - "metadata": { - "height": 98 - }, - "outputs": [], - "source": [ - "from langchain.chains import ConversationChain\n", - "from langchain.chat_models import ChatOpenAI\n", - "from langchain.memory import ConversationBufferMemory" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "88bdf13d", - "metadata": { - "height": 133 - }, - "outputs": [], - "source": [ - "# 这里我们将参数temperature设置为0.0,从而减少生成答案的随机性。\n", - "# 如果你想要每次得到不一样的有新意的答案,可以尝试增大该参数。\n", - "llm = ChatOpenAI(temperature=0.0) \n", - "\n", - "memory = ConversationBufferMemory()\n", - "\n", - "# 新建一个 ConversationChain Class 实例\n", - "# verbose参数设置为True时,程序会输出更详细的信息,以提供更多的调试或运行时信息。\n", - "# 相反,当将verbose参数设置为False时,程序会以更简洁的方式运行,只输出关键的信息。\n", - "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )" - ] - }, - { - "cell_type": "markdown", - "id": "dea83837", - "metadata": { - "tags": [] - }, - "source": [ - "#### 2.1.2 第一轮对话" - ] - }, - { - "cell_type": "markdown", - "id": "1a3b4c42", - "metadata": {}, - "source": [ - "当我们运行预测(predict)时,生成了一些提示,如下所见,他说“以下是人类和AI之间友好的对话,AI健谈“等等,这实际上是LangChain生成的提示,以使系统进行希望和友好的对话,并且必须保存对话,并提示了当前已完成的模型链。" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "db24677d", - "metadata": { - "height": 47 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "\n", - "Human: Hi, my name is Andrew\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "\"Hello Andrew! It's nice to meet you. How can I assist you today?\"" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"Hi, my name is Andrew\")" - ] - }, - { - "cell_type": "markdown", - "id": "e71564ad", - "metadata": {}, - "source": [ - "#### 2.1.3 第二轮对话" - ] - }, - { - "cell_type": "markdown", - "id": "54d006bd", - "metadata": {}, - "source": [ - "当我们进行第二轮对话时,它会保留上面的提示" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "cc3ef937", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "Human: Hi, my name is Andrew\n", - "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", - "Human: What is 1+1?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'1+1 is equal to 2.'" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"What is 1+1?\")" - ] - }, - { - "cell_type": "markdown", - "id": "33cb734b", - "metadata": {}, - "source": [ - "#### 2.1.4 第三轮对话" - ] - }, - { - "cell_type": "markdown", - "id": "0393df3d", - "metadata": {}, - "source": [ - "为了验证他是否记忆了前面的对话内容,我们让他回答前面已经说过的内容(我的名字),可以看到他确实输出了正确的名字,因此这个对话链随着往下进行会越来越长" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "acf3339a", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "Human: Hi, my name is Andrew\n", - "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", - "Human: What is 1+1?\n", - "AI: 1+1 is equal to 2.\n", - "Human: What is my name?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'Your name is Andrew.'" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"What is my name?\")" - ] - }, - { - "cell_type": "markdown", - "id": "5a96a8d9", - "metadata": {}, - "source": [ - "#### 2.1.5 查看储存缓存\n", - "\n", - "储存缓存(memory.buffer)\n", - "储存了当前为止所有的对话信息" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "2529400d", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Human: Hi, my name is Andrew\n", - "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", - "Human: What is 1+1?\n", - "AI: 1+1 is equal to 2.\n", - "Human: What is my name?\n", - "AI: Your name is Andrew.\n" - ] - } - ], - "source": [ - "print(memory.buffer) " - ] - }, - { - "cell_type": "markdown", - "id": "0b5de846", - "metadata": {}, - "source": [ - "也可以通过memory.load_memory_variables({})打印缓存中的历史消息。这里的`{}`是一个空字典,有一些更高级的功能,使用户可以使用更复杂的输入,但我们不会在这个短期课程中讨论它们,所以不要担心为什么这里有一个空的花括号。" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "5018cb0a", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'history': \"Human: Hi, my name is Andrew\\nAI: Hello Andrew! It's nice to meet you. How can I assist you today?\\nHuman: What is 1+1?\\nAI: 1+1 is equal to 2.\\nHuman: What is my name?\\nAI: Your name is Andrew.\"}\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({}))" - ] - }, - { - "cell_type": "markdown", - "id": "07d2e892", - "metadata": {}, - "source": [ - "#### 2.1.6 直接添加内容到储存缓存" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "14219b70", - "metadata": { - "height": 31 - }, - "outputs": [], - "source": [ - "memory = ConversationBufferMemory() # 新建一个空的对话缓存记忆" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "a36e9905", - "metadata": { - "height": 48 - }, - "outputs": [], - "source": [ - "memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"}) # 向缓存区添加指定对话的输入输出" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "61631b1f", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Human: Hi\n", - "AI: What's up\n" - ] - } - ], - "source": [ - "print(memory.buffer) # 查看缓存区结果" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "a2fdf9ec", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'history': \"Human: Hi\\nAI: What's up\"}\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({}))# 再次加载记忆变量" - ] - }, - { - "cell_type": "markdown", - "id": "2ac544f2", - "metadata": {}, - "source": [ - "继续添加新的内容,对话历史都保存下来在了!" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "7ca79256", - "metadata": { - "height": 64 - }, - "outputs": [], - "source": [ - "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "890a4497", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': \"Human: Hi\\nAI: What's up\\nHuman: Not much, just hanging\\nAI: Cool\"}" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "6eddd91a-bf1c-4b82-b99c-c585420e4ecb", - "metadata": {}, - "source": [ - "### 2.2 中文版" - ] - }, - { - "cell_type": "markdown", - "id": "55b3e4e9-7a6a-4a09-9ac3-0096a67849c7", - "metadata": {}, - "source": [ - "#### 2.1.1 初始化对话模型" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "3577aaff-7edb-40b0-866a-e407e63d55e0", - "metadata": { - "height": 98 - }, - "outputs": [], - "source": [ - "from langchain.chains import ConversationChain\n", - "from langchain.chat_models import ChatOpenAI\n", - "from langchain.memory import ConversationBufferMemory" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "a77d37ab-1f75-4ae8-8d7c-5066773ead81", - "metadata": { - "height": 133 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "\n", - "Human: 你好, 我叫皮皮鲁\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "llm = ChatOpenAI(temperature=0.0) \n", - "\n", - "memory = ConversationBufferMemory()\n", - "\n", - "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )" - ] - }, - { - "cell_type": "markdown", - "id": "747cb539-abc4-4e47-8cb9-1ee608ab07fc", - "metadata": {}, - "source": [ - "#### 2.1.2 第一轮对话" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99e48462-7a92-4842-bdaa-2a478ba2252c", - "metadata": {}, - "outputs": [], - "source": [ - "conversation.predict(input=\"你好, 我叫皮皮鲁\")" - ] - }, - { - "cell_type": "markdown", - "id": "979d320b-6b20-4722-99db-c48a43711d6c", - "metadata": {}, - "source": [ - "#### 2.1.3 第二轮对话" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "6ed6e97a-d7ea-4188-a6d7-f91d2a29d14a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "Human: 你好, 我叫皮皮鲁\n", - "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", - "Human: 1+1等于多少?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'1+1等于2。'" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"1+1等于多少?\")" - ] - }, - { - "cell_type": "markdown", - "id": "8a1fd531-216e-42d8-b226-839747ad7dd3", - "metadata": {}, - "source": [ - "#### 2.1.4 第三轮对话" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b5dfe488-2758-42c7-9c20-e483b4c22ab8", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "Human: 你好, 我叫皮皮鲁\n", - "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", - "Human: 1+1等于多少?\n", - "AI: 1+1等于2。\n", - "Human: What is my name?\n", - "AI: 你的名字是皮皮鲁。\n", - "Human: 我叫什么名字?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'你叫皮皮鲁。'" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"我叫什么名字?\")" - ] - }, - { - "cell_type": "markdown", - "id": "05d9822e-943d-4905-a1f8-a0d28c215d60", - "metadata": {}, - "source": [ - "#### 2.1.5 查看储存缓存" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "0795580f-b6b6-47e0-8882-26fe204560bd", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Human: 你好, 我叫皮皮鲁\n", - "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", - "Human: 1+1等于多少?\n", - "AI: 1+1等于2。\n", - "Human: What is my name?\n", - "AI: 你的名字是皮皮鲁。\n", - "Human: 我叫什么名字?\n", - "AI: 你叫皮皮鲁。\n" - ] - } - ], - "source": [ - "print(memory.buffer) " - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "dfe7824f-bd6e-4b95-92e2-1c85c62a92e9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Human: 你好, 我叫皮皮鲁\n", - "AI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", - "Human: 1+1等于多少?\n", - "AI: 1+1等于2。\n", - "Human: What is my name?\n", - "AI: 你的名字是皮皮鲁。\n", - "Human: 我叫什么名字?\n", - "AI: 你叫皮皮鲁。\n" - ] - } - ], - "source": [ - "print(memory.buffer) " - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "48942759-8afb-4aed-80c5-a48952a2b0c0", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'history': 'Human: 你好, 我叫皮皮鲁\\nAI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\\nHuman: 1+1等于多少?\\nAI: 1+1等于2。\\nHuman: What is my name?\\nAI: 你的名字是皮皮鲁。\\nHuman: 我叫什么名字?\\nAI: 你叫皮皮鲁。'}\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({}))" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "4d0c4625-e928-45dc-b8da-4ab865ac5f7e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: 你好, 我叫皮皮鲁\\nAI: 你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\\nHuman: 1+1等于多少?\\nAI: 1+1等于2。\\nHuman: What is my name?\\nAI: 你的名字是皮皮鲁。\\nHuman: 我叫什么名字?\\nAI: 你叫皮皮鲁。'}" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "80f3778e-5fbf-43ed-9df1-d57d98ec6fb0", - "metadata": {}, - "source": [ - "#### 2.1.6 直接添加内容到储存缓存" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "147b2c30-1662-4b49-aaf8-c228428e5cc6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西'}" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory = ConversationBufferMemory()\n", - "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "6b5e27f0-dad7-41b6-9326-bebf6299638f", - "metadata": { - "height": 64 - }, - "outputs": [], - "source": [ - "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "cfa7c555-06ab-4906-b3dc-906f789e08f5", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool'}" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "deb33de8-37ea-4180-a73e-0fc456b14eb0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: 你好,我叫皮皮鲁\\nAI: 你好啊,我叫鲁西西\\nHuman: Not much, just hanging\\nAI: Cool\\nHuman: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "10146f1a-0114-4902-8122-d19ae6f7c461", - "metadata": {}, - "source": [ - "### 2.3 总结" - ] - }, - { - "cell_type": "markdown", - "id": "2759b6bc-edb2-4cfe-b0f8-1bf6c4d796f9", - "metadata": {}, - "source": [ - "当我们在使用大型语言模型进行聊天对话时,**大型语言模型本身实际上是无状态的。语言模型本身并不记得到目前为止的历史对话**。每次调用API结点都是独立的。储存(Memory)可以储存到目前为止的所有术语或对话,并将其输入或附加上下文到LLM中用于生成输出。如此看起来就好像它在进行下一轮对话的时候,记得之前说过什么。\n" - ] - }, - { - "cell_type": "markdown", - "id": "cf98e9ff", - "metadata": {}, - "source": [ - "## 三、对话缓存窗口储存\n", - " \n", - "随着对话变得越来越长,所需的内存量也变得非常长。将大量的tokens发送到LLM的成本,也会变得更加昂贵,这也就是为什么API的调用费用,通常是基于它需要处理的tokens数量而收费的。\n", - " \n", - "针对以上问题,LangChain也提供了几种方便的储存方式来保存历史对话。其中,对话缓存窗口储存只保留一个窗口大小的对话。它只使用最近的n次交互。这可以用于保持最近交互的滑动窗口,以便缓冲区不会过大" - ] - }, - { - "cell_type": "markdown", - "id": "b63c9061-9916-4524-b497-93a0aa2b7d06", - "metadata": {}, - "source": [ - "### 3.1 英文版" - ] - }, - { - "cell_type": "markdown", - "id": "641477a4", - "metadata": {}, - "source": [ - "#### 3.1.1 添加两轮对话到窗口储存" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "3ea6233e", - "metadata": { - "height": 47 - }, - "outputs": [], - "source": [ - "from langchain.memory import ConversationBufferWindowMemory\n", - "\n", - "# k 为窗口参数,k=1表明只保留一个对话记忆\n", - "memory = ConversationBufferWindowMemory(k=1) " - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "dc4553fb", - "metadata": { - "height": 115 - }, - "outputs": [], - "source": [ - "# 向memory添加两轮对话\n", - "memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"})\n", - "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "6a788403", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: Not much, just hanging\\nAI: Cool'}" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 并查看记忆变量当前的记录\n", - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "63bda148", - "metadata": {}, - "source": [ - "#### 3.1.2 在对话链中应用窗口储存" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "4087bc87", - "metadata": { - "height": 133 - }, - "outputs": [], - "source": [ - "llm = ChatOpenAI(temperature=0.0)\n", - "memory = ConversationBufferWindowMemory(k=1)\n", - "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )" - ] - }, - { - "cell_type": "markdown", - "id": "b6d661e3", - "metadata": {}, - "source": [ - "注意此处!由于这里用的是一个窗口的记忆,因此只能保存一轮的历史消息,因此AI并不能知道你第一轮对话中提到的名字,他最多只能记住上一轮(第二轮)的对话信息" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "4faaa952", - "metadata": { - "height": 47 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\"Hello Andrew! It's nice to meet you. How can I assist you today?\"" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"Hi, my name is Andrew\")" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "bb20ddaa", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'1+1 is equal to 2.'" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"What is 1+1?\")" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "489b2194", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\"I'm sorry, but I don't have access to personal information.\"" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"What is my name?\")" - ] - }, - { - "cell_type": "markdown", - "id": "88837e7c-cf4b-469e-b820-bbfc49ba876c", - "metadata": {}, - "source": [ - "### 3.2 中文版" - ] - }, - { - "cell_type": "markdown", - "id": "760ec3ad-6959-4a36-b1b5-4fcafe8088ad", - "metadata": {}, - "source": [ - "#### 3.1.1 添加两轮对话到窗口储存" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "68a2907c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'Human: 很高兴和你成为朋友!\\nAI: 是的,让我们一起去冒险吧!'}" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from langchain.memory import ConversationBufferWindowMemory\n", - "\n", - "# k=1表明只保留一个对话记忆\n", - "memory = ConversationBufferWindowMemory(k=1) \n", - "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", - "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "dcabf017-5bfd-4904-9f06-388f994eddc9", - "metadata": {}, - "source": [ - "#### 3.1.2 在对话链中应用窗口储存" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "1ee854d9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "你好,皮皮鲁!很高兴认识你。我是一个AI助手,可以回答你的问题和提供帮助。有什么我可以帮你的吗?\n", - "1+1等于2。\n", - "很抱歉,我无法知道您的名字。\n" - ] - } - ], - "source": [ - "llm = ChatOpenAI(temperature=0.0)\n", - "memory = ConversationBufferWindowMemory(k=1)\n", - "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )\n", - "print(conversation.predict(input=\"你好, 我叫皮皮鲁\"))\n", - "print(conversation.predict(input=\"1+1等于多少?\"))\n", - "print(conversation.predict(input=\"我叫什么名字?\"))" - ] - }, - { - "cell_type": "markdown", - "id": "d2931b92", - "metadata": {}, - "source": [ - "## 四、对话token缓存储存" - ] - }, - { - "cell_type": "markdown", - "id": "dff5b4c7", - "metadata": {}, - "source": [ - "使用对话token缓存记忆,内存将限制保存的token数量。如果token数量超出指定数目,它会切掉这个对话的早期部分\n", - "以保留与最近的交流相对应的token数量,但不超过token限制。" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "id": "9f6d063c", - "metadata": { - "height": 31 - }, - "outputs": [], - "source": [ - "!pip install -q tiktoken " - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "id": "fb9020ed", - "metadata": { - "height": 81 - }, - "outputs": [], - "source": [ - "from langchain.llms import OpenAI\n", - "from langchain.memory import ConversationTokenBufferMemory" - ] - }, - { - "cell_type": "markdown", - "id": "f3a84112", - "metadata": {}, - "source": [ - "### 4.1 英文版\n", - "添加对话到Token缓存储存,限制token数量,进行测试" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "43582ee6", - "metadata": { - "height": 149 - }, - "outputs": [], - "source": [ - "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", - "memory.save_context({\"input\": \"AI is what?!\"}, {\"output\": \"Amazing!\"})\n", - "memory.save_context({\"input\": \"Backpropagation is what?\"}, {\"output\": \"Beautiful!\"})\n", - "memory.save_context({\"input\": \"Chatbots are what?\"}, {\"output\": \"Charming!\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "284288e1", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'AI: Beautiful!\\nHuman: Chatbots are what?\\nAI: Charming!'}" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "7b62b2e1", - "metadata": {}, - "source": [ - "可以看到前面超出的的token已经被舍弃了!!!" - ] - }, - { - "cell_type": "markdown", - "id": "f7f6be43", - "metadata": {}, - "source": [ - "### 4.2 中文版" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "e9191020", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': 'AI: 轻舟已过万重山。'}" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", - "memory.save_context({\"input\": \"朝辞白帝彩云间,\"}, {\"output\": \"千里江陵一日还。\"})\n", - "memory.save_context({\"input\": \"两岸猿声啼不住,\"}, {\"output\": \"轻舟已过万重山。\"})\n", - "memory.load_memory_variables({})" - ] - }, - { - "cell_type": "markdown", - "id": "fb08ef4a-876f-422a-81f9-4805288e5955", - "metadata": {}, - "source": [ - "### 4.3 补充" - ] - }, - { - "cell_type": "markdown", - "id": "5e4d918b", - "metadata": {}, - "source": [ - "ChatGPT使用一种基于字节对编码(Byte Pair Encoding,BPE)的方法来进行tokenization(将输入文本拆分为token)。BPE是一种常见的tokenization技术,它将输入文本分割成较小的子词单元。 \n", - "\n", - "OpenAI在其官方GitHub上公开了一个最新的开源Python库 [tiktoken](https://github.com/openai/tiktoken),这个库主要是用来计算tokens数量的。相比较HuggingFace的tokenizer,其速度提升了好几倍。\n", - "\n", - "具体token计算方式,特别是汉字和英文单词的token区别,具体课参考[知乎文章](https://www.zhihu.com/question/594159910) 。" - ] - }, - { - "cell_type": "markdown", - "id": "5ff55d5d", - "metadata": {}, - "source": [ - "## 五、对话摘要缓存储存" - ] - }, - { - "cell_type": "markdown", - "id": "7d39b83a", - "metadata": {}, - "source": [ - "对话摘要缓存储存,**使用LLM编写到目前为止历史对话的摘要**,并将其保存" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "72dcf8b1", - "metadata": { - "height": 64 - }, - "outputs": [], - "source": [ - "from langchain.chains import ConversationChain\n", - "from langchain.chat_models import ChatOpenAI\n", - "from langchain.memory import ConversationSummaryBufferMemory" - ] - }, - { - "cell_type": "markdown", - "id": "243b213e-ce17-46a0-8652-03658ca58dd8", - "metadata": {}, - "source": [ - "### 5.1 英文版" - ] - }, - { - "cell_type": "markdown", - "id": "6572ef39", - "metadata": {}, - "source": [ - "#### 5.1.1 使用对话摘要缓存储存\n", - "\n", - "创建一个长字符串,其中包含某人的日程安排" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "4a5b238f", - "metadata": { - "height": 285 - }, - "outputs": [], - "source": [ - "# 创建一个长字符串\n", - "schedule = \"There is a meeting at 8am with your product team. \\\n", - "You will need your powerpoint presentation prepared. \\\n", - "9am-12pm have time to work on your LangChain \\\n", - "project which will go quickly because Langchain is such a powerful tool. \\\n", - "At Noon, lunch at the italian resturant with a customer who is driving \\\n", - "from over an hour away to meet you to understand the latest in AI. \\\n", - "Be sure to bring your laptop to show the latest LLM demo.\"\n", - "\n", - "# 使用对话摘要缓存记忆\n", - "llm = ChatOpenAI(temperature=0.0)\n", - "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100) \n", - "memory.save_context({\"input\": \"Hello\"}, {\"output\": \"What's up\"})\n", - "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})\n", - "memory.save_context(\n", - " {\"input\": \"What is on the schedule today?\"}, {\"output\": f\"{schedule}\"}\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "15226a41-ab36-43a0-93f7-c03c6b374936", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({})['history'])" - ] - }, - { - "cell_type": "markdown", - "id": "7ccb97b6", - "metadata": {}, - "source": [ - "#### 5.1.2 基于对话摘要缓存储存的对话链\n", - "基于上面的对话摘要缓存储存,新建一个对话链" - ] - }, - { - "cell_type": "code", - "execution_count": 90, - "id": "6728edba", - "metadata": { - "height": 99 - }, - "outputs": [], - "source": [ - "conversation = ConversationChain(llm=llm, memory=memory, verbose=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 91, - "id": "9a221b1d", - "metadata": { - "height": 47 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n", - "Human: What would be a good demo to show?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.'" - ] - }, - "execution_count": 91, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"What would be a good demo to show?\")" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "id": "bb582617", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting. A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({})['history'])" - ] - }, - { - "cell_type": "markdown", - "id": "4ba827aa", - "metadata": { - "height": 31 - }, - "source": [ - "### 5.2 中文版" - ] - }, - { - "cell_type": "markdown", - "id": "64898f33-c538-4e68-b008-7123870b692b", - "metadata": {}, - "source": [ - "#### 5.2.1 使用对话摘要缓存储存\n", - "\n", - "创建一个长字符串,其中包含某人的日程安排" - ] - }, - { - "cell_type": "code", - "execution_count": 97, - "id": "2c07922b", - "metadata": { - "height": 31 - }, - "outputs": [], - "source": [ - "# 创建一个长字符串\n", - "schedule = \"在八点你和你的产品团队有一个会议。 \\\n", - "你需要做一个PPT。 \\\n", - "上午9点到12点你需要忙于LangChain。\\\n", - "Langchain是一个有用的工具,因此你的项目进展的非常快。\\\n", - "中午,在意大利餐厅与一位开车来的顾客共进午餐 \\\n", - "走了一个多小时的路程与你见面,只为了解最新的 AI。 \\\n", - "确保你带了笔记本电脑可以展示最新的 LLM 样例.\"\n", - "\n", - "llm = ChatOpenAI(temperature=0.0)\n", - "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)\n", - "memory.save_context({\"input\": \"你好,我叫皮皮鲁\"}, {\"output\": \"你好啊,我叫鲁西西\"})\n", - "memory.save_context({\"input\": \"很高兴和你成为朋友!\"}, {\"output\": \"是的,让我们一起去冒险吧!\"})\n", - "memory.save_context({\"input\": \"今天的日程安排是什么?\"}, {\"output\": f\"{schedule}\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 98, - "id": "17424a12-430f-4529-9067-300978c6169e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n" - ] - } - ], - "source": [ - "print(memory.load_memory_variables({})['history'])" - ] - }, - { - "cell_type": "markdown", - "id": "9e29a956-607a-4247-9eb5-01285a370991", - "metadata": {}, - "source": [ - "#### 5.1.2 基于对话摘要缓存储存的对话链\n", - "基于上面的对话摘要缓存储存,新建一个对话链" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "id": "52696c8c", - "metadata": { - "height": 31 - }, - "outputs": [], - "source": [ - "conversation = ConversationChain(llm=llm, memory=memory, verbose=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 100, - "id": "48690d13", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", - "\n", - "Current conversation:\n", - "System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n", - "Human: 展示什么样的样例最好呢?\n", - "AI:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n" - ] - }, - { - "data": { - "text/plain": [ - "'展示一些具有多样性和创新性的样例可能是最好的选择。你可以选择展示一些基于图像识别的样例,比如人脸识别、物体识别等。另外,你也可以展示一些自然语言处理方面的样例,比如文本生成、情感分析等。最重要的是选择那些能够展示出你们团队的技术实力和创造力的样例。'" - ] - }, - "execution_count": 100, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "conversation.predict(input=\"展示什么样的样例最好呢?\")" - ] - }, - { - "cell_type": "code", - "execution_count": 101, - "id": "85bba1f8", - "metadata": { - "height": 31 - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'history': \"System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples. The human asks what kind of samples would be best to showcase. The AI suggests that showcasing diverse and innovative samples would be the best choice. They recommend selecting samples based on image recognition, such as face recognition and object recognition. Additionally, they suggest showcasing samples related to natural language processing, such as text generation and sentiment analysis. The AI emphasizes the importance of choosing samples that demonstrate the team's technical expertise and creativity.\"}" - ] - }, - "execution_count": 101, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "memory.load_memory_variables({}) # 摘要记录更新了" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": false, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": true - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "a786c77c", "metadata": {"tags": []}, "source": ["# \u7b2c\u4e09\u7ae0 \u50a8\u5b58\n", "\n", " - [\u4e00\u3001\u8bbe\u7f6eOpenAI API Key](#\u4e00\u3001\u8bbe\u7f6eOpenAI-API-Key)\n", " - [\u4e8c\u3001\u5bf9\u8bdd\u7f13\u5b58\u50a8\u5b58](#\u4e8c\u3001\u5bf9\u8bdd\u7f13\u5b58\u50a8\u5b58)\n", " - [2.1 \u82f1\u6587\u7248](#2.1-\u82f1\u6587\u7248)\n", " - [2.1.1 \u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b](#2.1.1-\u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b)\n", " - [2.1.2 \u7b2c\u4e00\u8f6e\u5bf9\u8bdd](#2.1.2-\u7b2c\u4e00\u8f6e\u5bf9\u8bdd)\n", " - [2.1.3 \u7b2c\u4e8c\u8f6e\u5bf9\u8bdd](#2.1.3-\u7b2c\u4e8c\u8f6e\u5bf9\u8bdd)\n", " - [2.1.4 \u7b2c\u4e09\u8f6e\u5bf9\u8bdd](#2.1.4-\u7b2c\u4e09\u8f6e\u5bf9\u8bdd)\n", " - [2.1.5 \u67e5\u770b\u50a8\u5b58\u7f13\u5b58](#2.1.5-\u67e5\u770b\u50a8\u5b58\u7f13\u5b58)\n", " - [2.1.6 \u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58](#2.1.6-\u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58)\n", " - [2.2 \u4e2d\u6587\u7248](#2.2-\u4e2d\u6587\u7248)\n", " - [2.1.1 \u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b](#2.1.1-\u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b)\n", " - [2.1.2 \u7b2c\u4e00\u8f6e\u5bf9\u8bdd](#2.1.2-\u7b2c\u4e00\u8f6e\u5bf9\u8bdd)\n", " - [2.1.3 \u7b2c\u4e8c\u8f6e\u5bf9\u8bdd](#2.1.3-\u7b2c\u4e8c\u8f6e\u5bf9\u8bdd)\n", " - [2.1.4 \u7b2c\u4e09\u8f6e\u5bf9\u8bdd](#2.1.4-\u7b2c\u4e09\u8f6e\u5bf9\u8bdd)\n", " - [2.1.5 \u67e5\u770b\u50a8\u5b58\u7f13\u5b58](#2.1.5-\u67e5\u770b\u50a8\u5b58\u7f13\u5b58)\n", " - [2.1.6 \u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58](#2.1.6-\u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58)\n", " - [2.3 \u603b\u7ed3](#2.3-\u603b\u7ed3)\n", " - [\u4e09\u3001\u5bf9\u8bdd\u7f13\u5b58\u7a97\u53e3\u50a8\u5b58](#\u4e09\u3001\u5bf9\u8bdd\u7f13\u5b58\u7a97\u53e3\u50a8\u5b58)\n", " - [3.1 \u82f1\u6587\u7248](#3.1-\u82f1\u6587\u7248)\n", " - [3.1.1 \u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58](#3.1.1-\u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58)\n", " - [3.1.2 \u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58](#3.1.2-\u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58)\n", " - [3.2 \u4e2d\u6587\u7248](#3.2-\u4e2d\u6587\u7248)\n", " - [3.1.1 \u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58](#3.1.1-\u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58)\n", " - [3.1.2 \u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58](#3.1.2-\u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58)\n", " - [\u56db\u3001\u5bf9\u8bddtoken\u7f13\u5b58\u50a8\u5b58](#\u56db\u3001\u5bf9\u8bddtoken\u7f13\u5b58\u50a8\u5b58)\n", " - [4.1 \u82f1\u6587\u7248](#4.1-\u82f1\u6587\u7248)\n", " - [4.2 \u4e2d\u6587\u7248](#4.2-\u4e2d\u6587\u7248)\n", " - [4.3 \u8865\u5145](#4.3-\u8865\u5145)\n", " - [\u4e94\u3001\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58](#\u4e94\u3001\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58)\n", " - [5.1 \u82f1\u6587\u7248](#5.1-\u82f1\u6587\u7248)\n", " - [5.1.1 \u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58](#5.1.1-\u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58)\n", " - [5.1.2 \u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe](#5.1.2-\u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe)\n", " - [5.2 \u4e2d\u6587\u7248](#5.2-\u4e2d\u6587\u7248)\n", " - [5.2.1 \u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58](#5.2.1-\u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58)\n", " - [5.1.2 \u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe](#5.1.2-\u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe)\n"]}, {"cell_type": "markdown", "id": "7e10db6f", "metadata": {}, "source": ["\u5f53\u4f60\u4e0e\u90a3\u4e9b\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u4ea4\u4e92\u7684\u65f6\u5019\uff0c\u4ed6\u4eec\u4e0d\u4f1a\u8bb0\u5f97\u4f60\u4e4b\u524d\u548c\u4ed6\u8fdb\u884c\u7684\u4ea4\u6d41\u5185\u5bb9\uff0c\u8fd9\u5728\u6211\u4eec\u6784\u5efa\u4e00\u4e9b\u5e94\u7528\u7a0b\u5e8f\uff08\u5982\u804a\u5929\u673a\u5668\u4eba\uff09\u7684\u65f6\u5019\uff0c\u662f\u4e00\u4e2a\u5f88\u5927\u7684\u95ee\u9898 -- \u663e\u5f97\u4e0d\u591f\u667a\u80fd\uff01\u56e0\u6b64\uff0c\u5728\u672c\u8282\u4e2d\u6211\u4eec\u5c06\u4ecb\u7ecd LangChain \u4e2d\u7684\u50a8\u5b58\u6a21\u5757\uff0c\u5373\u5982\u4f55\u5c06\u5148\u524d\u7684\u5bf9\u8bdd\u5d4c\u5165\u5230\u8bed\u8a00\u6a21\u578b\u4e2d\u7684\uff0c\u4f7f\u5176\u5177\u6709\u8fde\u7eed\u5bf9\u8bdd\u7684\u80fd\u529b\u3002\n", "\n", "\u5f53\u4f7f\u7528 LangChain \u4e2d\u7684\u50a8\u5b58(Memory)\u6a21\u5757\u65f6\uff0c\u5b83\u53ef\u4ee5\u5e2e\u52a9\u4fdd\u5b58\u548c\u7ba1\u7406\u5386\u53f2\u804a\u5929\u6d88\u606f\uff0c\u4ee5\u53ca\u6784\u5efa\u5173\u4e8e\u7279\u5b9a\u5b9e\u4f53\u7684\u77e5\u8bc6\u3002\u8fd9\u4e9b\u7ec4\u4ef6\u53ef\u4ee5\u8de8\u591a\u8f6e\u5bf9\u8bdd\u50a8\u5b58\u4fe1\u606f\uff0c\u5e76\u5141\u8bb8\u5728\u5bf9\u8bdd\u671f\u95f4\u8ddf\u8e2a\u7279\u5b9a\u4fe1\u606f\u548c\u4e0a\u4e0b\u6587\u3002\n", "\n", "LangChain \u63d0\u4f9b\u4e86\u591a\u79cd\u50a8\u5b58\u7c7b\u578b\u3002\u5176\u4e2d\uff0c\u7f13\u51b2\u533a\u50a8\u5b58\u5141\u8bb8\u4fdd\u7559\u6700\u8fd1\u7684\u804a\u5929\u6d88\u606f\uff0c\u6458\u8981\u50a8\u5b58\u5219\u63d0\u4f9b\u4e86\u5bf9\u6574\u4e2a\u5bf9\u8bdd\u7684\u6458\u8981\u3002\u5b9e\u4f53\u50a8\u5b58 \u5219\u5141\u8bb8\u5728\u591a\u8f6e\u5bf9\u8bdd\u4e2d\u4fdd\u7559\u6709\u5173\u7279\u5b9a\u5b9e\u4f53\u7684\u4fe1\u606f\u3002\u8fd9\u4e9b\u8bb0\u5fc6\u7ec4\u4ef6\u90fd\u662f\u6a21\u5757\u5316\u7684\uff0c\u53ef\u4e0e\u5176\u4ed6\u7ec4\u4ef6\u7ec4\u5408\u4f7f\u7528\uff0c\u4ece\u800c\u589e\u5f3a\u673a\u5668\u4eba\u7684\u5bf9\u8bdd\u7ba1\u7406\u80fd\u529b\u3002\u50a8\u5b58\u6a21\u5757\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684API\u8c03\u7528\u6765\u8bbf\u95ee\u548c\u66f4\u65b0\uff0c\u5141\u8bb8\u5f00\u53d1\u4eba\u5458\u66f4\u8f7b\u677e\u5730\u5b9e\u73b0\u5bf9\u8bdd\u5386\u53f2\u8bb0\u5f55\u7684\u7ba1\u7406\u548c\u7ef4\u62a4\u3002\n", "\n", "\u6b64\u6b21\u8bfe\u7a0b\u4e3b\u8981\u4ecb\u7ecd\u5176\u4e2d\u56db\u79cd\u50a8\u5b58\u6a21\u5757\uff0c\u5176\u4ed6\u6a21\u5757\u53ef\u67e5\u770b\u6587\u6863\u5b66\u4e60\u3002\n", "- \u5bf9\u8bdd\u7f13\u5b58\u50a8\u5b58 (ConversationBufferMemory\uff09\n", "- \u5bf9\u8bdd\u7f13\u5b58\u7a97\u53e3\u50a8\u5b58 (ConversationBufferWindowMemory\uff09\n", "- \u5bf9\u8bdd\u4ee4\u724c\u7f13\u5b58\u50a8\u5b58 (ConversationTokenBufferMemory\uff09\n", "- \u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58 (ConversationSummaryBufferMemory\uff09\n", "\n", "\u5728LangChain\u4e2d\uff0c\u50a8\u5b58 \u6307\u7684\u662f\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u7684\u77ed\u671f\u8bb0\u5fc6\u3002\u4e3a\u4ec0\u4e48\u662f\u77ed\u671f\u8bb0\u5fc6\uff1f\u90a3\u662f\u56e0\u4e3aLLM\u8bad\u7ec3\u597d\u4e4b\u540e (\u83b7\u5f97\u4e86\u4e00\u4e9b\u957f\u671f\u8bb0\u5fc6)\uff0c\u5b83\u7684\u53c2\u6570\u4fbf\u4e0d\u4f1a\u56e0\u4e3a\u7528\u6237\u7684\u8f93\u5165\u800c\u53d1\u751f\u6539\u53d8\u3002\u5f53\u7528\u6237\u4e0e\u8bad\u7ec3\u597d\u7684LLM\u8fdb\u884c\u5bf9\u8bdd\u65f6\uff0cLLM\u4f1a\u6682\u65f6\u8bb0\u4f4f\u7528\u6237\u7684\u8f93\u5165\u548c\u5b83\u5df2\u7ecf\u751f\u6210\u7684\u8f93\u51fa\uff0c\u4ee5\u4fbf\u9884\u6d4b\u4e4b\u540e\u7684\u8f93\u51fa\uff0c\u800c\u6a21\u578b\u8f93\u51fa\u5b8c\u6bd5\u540e\uff0c\u5b83\u4fbf\u4f1a\u201c\u9057\u5fd8\u201d\u4e4b\u524d\u7528\u6237\u7684\u8f93\u5165\u548c\u5b83\u7684\u8f93\u51fa\u3002\u56e0\u6b64\uff0c\u4e4b\u524d\u7684\u8fd9\u4e9b\u4fe1\u606f\u53ea\u80fd\u79f0\u4f5c\u4e3aLLM\u7684\u77ed\u671f\u8bb0\u5fc6\u3002 \n", " \n", "\u4e3a\u4e86\u5ef6\u957fLLM\u77ed\u671f\u8bb0\u5fc6\u7684\u4fdd\u7559\u65f6\u95f4\uff0c\u5219\u9700\u8981\u501f\u52a9\u4e00\u4e9b\u5916\u90e8\u50a8\u5b58\u65b9\u5f0f\u6765\u8fdb\u884c\u8bb0\u5fc6\uff0c\u4ee5\u4fbf\u5728\u7528\u6237\u4e0eLLM\u5bf9\u8bdd\u4e2d\uff0cLLM\u80fd\u591f\u5c3d\u53ef\u80fd\u7684\u77e5\u9053\u7528\u6237\u4e0e\u5b83\u6240\u8fdb\u884c\u7684\u5386\u53f2\u5bf9\u8bdd\u4fe1\u606f\u3002 "]}, {"cell_type": "markdown", "id": "1ca56e6b-1e07-4405-a1ca-f4237f20fa75", "metadata": {"jp-MarkdownHeadingCollapsed": true, "tags": []}, "source": ["## \u4e00\u3001\u8bbe\u7f6eOpenAI API Key\n", "\n", "\u767b\u9646 [OpenAI \u8d26\u6237](https://platform.openai.com/account/api-keys) \u83b7\u53d6API Key\uff0c\u7136\u540e\u5c06\u5176\u8bbe\u7f6e\u4e3a\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "- \u5982\u679c\u4f60\u60f3\u8981\u8bbe\u7f6e\u4e3a\u5168\u5c40\u73af\u5883\u53d8\u91cf\uff0c\u53ef\u4ee5\u53c2\u8003[\u77e5\u4e4e\u6587\u7ae0](https://zhuanlan.zhihu.com/p/627665725)\u3002\n", "- \u5982\u679c\u4f60\u60f3\u8981\u8bbe\u7f6e\u4e3a\u672c\u5730/\u9879\u76ee\u73af\u5883\u53d8\u91cf\uff0c\u5728\u672c\u6587\u4ef6\u76ee\u5f55\u4e0b\u521b\u5efa`.env`\u6587\u4ef6, \u6253\u5f00\u6587\u4ef6\u8f93\u5165\u4ee5\u4e0b\u5185\u5bb9\u3002\n", "\n", "\n", " OPENAI_API_KEY=\"your_api_key\" \n", "
\n", " \n", " \u66ff\u6362\"your_api_key\"\u4e3a\u4f60\u81ea\u5df1\u7684 API Key"]}, {"cell_type": "code", "execution_count": null, "id": "6932bd47-c6d5-4794-8102-a12b84412a93", "metadata": {}, "outputs": [], "source": ["# \u4e0b\u8f7d\u9700\u8981\u7684\u5305python-dotenv\u548copenai\n", "# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q\n", "!pip install -q python-dotenv\n", "!pip install -q openai"]}, {"cell_type": "code", "execution_count": 1, "id": "10446712-9fa6-4d71-94ce-2ea4cf197e54", "metadata": {}, "outputs": [], "source": ["import os\n", "\n", "import openai\n", "from dotenv import find_dotenv, load_dotenv\n", "\n", "# \u8bfb\u53d6\u672c\u5730/\u9879\u76ee\u7684\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "# find_dotenv()\u5bfb\u627e\u5e76\u5b9a\u4f4d.env\u6587\u4ef6\u7684\u8def\u5f84\n", "# load_dotenv()\u8bfb\u53d6\u8be5.env\u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u5230\u5f53\u524d\u7684\u8fd0\u884c\u73af\u5883\u4e2d\n", "# \u5982\u679c\u4f60\u8bbe\u7f6e\u7684\u662f\u5168\u5c40\u7684\u73af\u5883\u53d8\u91cf\uff0c\u8fd9\u884c\u4ee3\u7801\u5219\u6ca1\u6709\u4efb\u4f55\u4f5c\u7528\u3002\n", "_ = load_dotenv(find_dotenv())\n", "\n", "# \u83b7\u53d6\u73af\u5883\u53d8\u91cf OPENAI_API_KEY\n", "openai.api_key = os.environ[\"OPENAI_API_KEY\"]"]}, {"cell_type": "markdown", "id": "1297dcd5", "metadata": {"tags": []}, "source": ["## \u4e8c\u3001\u5bf9\u8bdd\u7f13\u5b58\u50a8\u5b58\n", " "]}, {"cell_type": "markdown", "id": "ffa8cd26-45c5-4bae-90b2-b07d23bf3bb2", "metadata": {}, "source": ["### 2.1 \u82f1\u6587\u7248"]}, {"cell_type": "markdown", "id": "b7e77a3d-7aaa-48c1-b219-19bd6f4eb674", "metadata": {"tags": []}, "source": ["#### 2.1.1 \u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b"]}, {"cell_type": "code", "execution_count": 47, "id": "20ad6fe2", "metadata": {"height": 98}, "outputs": [], "source": ["from langchain.chains import ConversationChain\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain.memory import ConversationBufferMemory"]}, {"cell_type": "code", "execution_count": 48, "id": "88bdf13d", "metadata": {"height": 133}, "outputs": [], "source": ["# \u8fd9\u91cc\u6211\u4eec\u5c06\u53c2\u6570temperature\u8bbe\u7f6e\u4e3a0.0\uff0c\u4ece\u800c\u51cf\u5c11\u751f\u6210\u7b54\u6848\u7684\u968f\u673a\u6027\u3002\n", "# \u5982\u679c\u4f60\u60f3\u8981\u6bcf\u6b21\u5f97\u5230\u4e0d\u4e00\u6837\u7684\u6709\u65b0\u610f\u7684\u7b54\u6848\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u589e\u5927\u8be5\u53c2\u6570\u3002\n", "llm = ChatOpenAI(temperature=0.0) \n", "\n", "memory = ConversationBufferMemory()\n", "\n", "# \u65b0\u5efa\u4e00\u4e2a ConversationChain Class \u5b9e\u4f8b\n", "# verbose\u53c2\u6570\u8bbe\u7f6e\u4e3aTrue\u65f6\uff0c\u7a0b\u5e8f\u4f1a\u8f93\u51fa\u66f4\u8be6\u7ec6\u7684\u4fe1\u606f\uff0c\u4ee5\u63d0\u4f9b\u66f4\u591a\u7684\u8c03\u8bd5\u6216\u8fd0\u884c\u65f6\u4fe1\u606f\u3002\n", "# \u76f8\u53cd\uff0c\u5f53\u5c06verbose\u53c2\u6570\u8bbe\u7f6e\u4e3aFalse\u65f6\uff0c\u7a0b\u5e8f\u4f1a\u4ee5\u66f4\u7b80\u6d01\u7684\u65b9\u5f0f\u8fd0\u884c\uff0c\u53ea\u8f93\u51fa\u5173\u952e\u7684\u4fe1\u606f\u3002\n", "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )"]}, {"cell_type": "markdown", "id": "dea83837", "metadata": {"tags": []}, "source": ["#### 2.1.2 \u7b2c\u4e00\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "markdown", "id": "1a3b4c42", "metadata": {}, "source": ["\u5f53\u6211\u4eec\u8fd0\u884c\u9884\u6d4b(predict)\u65f6\uff0c\u751f\u6210\u4e86\u4e00\u4e9b\u63d0\u793a\uff0c\u5982\u4e0b\u6240\u89c1\uff0c\u4ed6\u8bf4\u201c\u4ee5\u4e0b\u662f\u4eba\u7c7b\u548cAI\u4e4b\u95f4\u53cb\u597d\u7684\u5bf9\u8bdd\uff0cAI\u5065\u8c08\u201c\u7b49\u7b49\uff0c\u8fd9\u5b9e\u9645\u4e0a\u662fLangChain\u751f\u6210\u7684\u63d0\u793a\uff0c\u4ee5\u4f7f\u7cfb\u7edf\u8fdb\u884c\u5e0c\u671b\u548c\u53cb\u597d\u7684\u5bf9\u8bdd\uff0c\u5e76\u4e14\u5fc5\u987b\u4fdd\u5b58\u5bf9\u8bdd\uff0c\u5e76\u63d0\u793a\u4e86\u5f53\u524d\u5df2\u5b8c\u6210\u7684\u6a21\u578b\u94fe\u3002"]}, {"cell_type": "code", "execution_count": 49, "id": "db24677d", "metadata": {"height": 47}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "\n", "Human: Hi, my name is Andrew\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["\"Hello Andrew! It's nice to meet you. How can I assist you today?\""]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"Hi, my name is Andrew\")"]}, {"cell_type": "markdown", "id": "e71564ad", "metadata": {}, "source": ["#### 2.1.3 \u7b2c\u4e8c\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "markdown", "id": "54d006bd", "metadata": {}, "source": ["\u5f53\u6211\u4eec\u8fdb\u884c\u7b2c\u4e8c\u8f6e\u5bf9\u8bdd\u65f6\uff0c\u5b83\u4f1a\u4fdd\u7559\u4e0a\u9762\u7684\u63d0\u793a"]}, {"cell_type": "code", "execution_count": 50, "id": "cc3ef937", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: Hi, my name is Andrew\n", "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", "Human: What is 1+1?\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'1+1 is equal to 2.'"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"What is 1+1?\")"]}, {"cell_type": "markdown", "id": "33cb734b", "metadata": {}, "source": ["#### 2.1.4 \u7b2c\u4e09\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "markdown", "id": "0393df3d", "metadata": {}, "source": ["\u4e3a\u4e86\u9a8c\u8bc1\u4ed6\u662f\u5426\u8bb0\u5fc6\u4e86\u524d\u9762\u7684\u5bf9\u8bdd\u5185\u5bb9\uff0c\u6211\u4eec\u8ba9\u4ed6\u56de\u7b54\u524d\u9762\u5df2\u7ecf\u8bf4\u8fc7\u7684\u5185\u5bb9\uff08\u6211\u7684\u540d\u5b57\uff09\uff0c\u53ef\u4ee5\u770b\u5230\u4ed6\u786e\u5b9e\u8f93\u51fa\u4e86\u6b63\u786e\u7684\u540d\u5b57\uff0c\u56e0\u6b64\u8fd9\u4e2a\u5bf9\u8bdd\u94fe\u968f\u7740\u5f80\u4e0b\u8fdb\u884c\u4f1a\u8d8a\u6765\u8d8a\u957f"]}, {"cell_type": "code", "execution_count": 51, "id": "acf3339a", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: Hi, my name is Andrew\n", "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", "Human: What is 1+1?\n", "AI: 1+1 is equal to 2.\n", "Human: What is my name?\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'Your name is Andrew.'"]}, "execution_count": 51, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"What is my name?\")"]}, {"cell_type": "markdown", "id": "5a96a8d9", "metadata": {}, "source": ["#### 2.1.5 \u67e5\u770b\u50a8\u5b58\u7f13\u5b58\n", "\n", "\u50a8\u5b58\u7f13\u5b58(memory.buffer)\n", "\u50a8\u5b58\u4e86\u5f53\u524d\u4e3a\u6b62\u6240\u6709\u7684\u5bf9\u8bdd\u4fe1\u606f"]}, {"cell_type": "code", "execution_count": 52, "id": "2529400d", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Human: Hi, my name is Andrew\n", "AI: Hello Andrew! It's nice to meet you. How can I assist you today?\n", "Human: What is 1+1?\n", "AI: 1+1 is equal to 2.\n", "Human: What is my name?\n", "AI: Your name is Andrew.\n"]}], "source": ["print(memory.buffer) "]}, {"cell_type": "markdown", "id": "0b5de846", "metadata": {}, "source": ["\u4e5f\u53ef\u4ee5\u901a\u8fc7memory.load_memory_variables({})\u6253\u5370\u7f13\u5b58\u4e2d\u7684\u5386\u53f2\u6d88\u606f\u3002\u8fd9\u91cc\u7684`{}`\u662f\u4e00\u4e2a\u7a7a\u5b57\u5178\uff0c\u6709\u4e00\u4e9b\u66f4\u9ad8\u7ea7\u7684\u529f\u80fd\uff0c\u4f7f\u7528\u6237\u53ef\u4ee5\u4f7f\u7528\u66f4\u590d\u6742\u7684\u8f93\u5165\uff0c\u4f46\u6211\u4eec\u4e0d\u4f1a\u5728\u8fd9\u4e2a\u77ed\u671f\u8bfe\u7a0b\u4e2d\u8ba8\u8bba\u5b83\u4eec\uff0c\u6240\u4ee5\u4e0d\u8981\u62c5\u5fc3\u4e3a\u4ec0\u4e48\u8fd9\u91cc\u6709\u4e00\u4e2a\u7a7a\u7684\u82b1\u62ec\u53f7\u3002"]}, {"cell_type": "code", "execution_count": 53, "id": "5018cb0a", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["{'history': \"Human: Hi, my name is Andrew\\nAI: Hello Andrew! It's nice to meet you. How can I assist you today?\\nHuman: What is 1+1?\\nAI: 1+1 is equal to 2.\\nHuman: What is my name?\\nAI: Your name is Andrew.\"}\n"]}], "source": ["print(memory.load_memory_variables({}))"]}, {"cell_type": "markdown", "id": "07d2e892", "metadata": {}, "source": ["#### 2.1.6 \u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58"]}, {"cell_type": "code", "execution_count": 54, "id": "14219b70", "metadata": {"height": 31}, "outputs": [], "source": ["memory = ConversationBufferMemory() # \u65b0\u5efa\u4e00\u4e2a\u7a7a\u7684\u5bf9\u8bdd\u7f13\u5b58\u8bb0\u5fc6"]}, {"cell_type": "code", "execution_count": 55, "id": "a36e9905", "metadata": {"height": 48}, "outputs": [], "source": ["memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"}) # \u5411\u7f13\u5b58\u533a\u6dfb\u52a0\u6307\u5b9a\u5bf9\u8bdd\u7684\u8f93\u5165\u8f93\u51fa"]}, {"cell_type": "code", "execution_count": 56, "id": "61631b1f", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Human: Hi\n", "AI: What's up\n"]}], "source": ["print(memory.buffer) # \u67e5\u770b\u7f13\u5b58\u533a\u7ed3\u679c"]}, {"cell_type": "code", "execution_count": 57, "id": "a2fdf9ec", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["{'history': \"Human: Hi\\nAI: What's up\"}\n"]}], "source": ["print(memory.load_memory_variables({}))# \u518d\u6b21\u52a0\u8f7d\u8bb0\u5fc6\u53d8\u91cf"]}, {"cell_type": "markdown", "id": "2ac544f2", "metadata": {}, "source": ["\u7ee7\u7eed\u6dfb\u52a0\u65b0\u7684\u5185\u5bb9\uff0c\u5bf9\u8bdd\u5386\u53f2\u90fd\u4fdd\u5b58\u4e0b\u6765\u5728\u4e86\uff01"]}, {"cell_type": "code", "execution_count": 58, "id": "7ca79256", "metadata": {"height": 64}, "outputs": [], "source": ["memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})"]}, {"cell_type": "code", "execution_count": 59, "id": "890a4497", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["{'history': \"Human: Hi\\nAI: What's up\\nHuman: Not much, just hanging\\nAI: Cool\"}"]}, "execution_count": 59, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "6eddd91a-bf1c-4b82-b99c-c585420e4ecb", "metadata": {}, "source": ["### 2.2 \u4e2d\u6587\u7248"]}, {"cell_type": "markdown", "id": "55b3e4e9-7a6a-4a09-9ac3-0096a67849c7", "metadata": {}, "source": ["#### 2.1.1 \u521d\u59cb\u5316\u5bf9\u8bdd\u6a21\u578b"]}, {"cell_type": "code", "execution_count": 30, "id": "3577aaff-7edb-40b0-866a-e407e63d55e0", "metadata": {"height": 98}, "outputs": [], "source": ["from langchain.chains import ConversationChain\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain.memory import ConversationBufferMemory"]}, {"cell_type": "code", "execution_count": 33, "id": "a77d37ab-1f75-4ae8-8d7c-5066773ead81", "metadata": {"height": 133}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "\n", "Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'\u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f'"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["llm = ChatOpenAI(temperature=0.0) \n", "\n", "memory = ConversationBufferMemory()\n", "\n", "conversation = ConversationChain(llm=llm, memory = memory, verbose=True )"]}, {"cell_type": "markdown", "id": "747cb539-abc4-4e47-8cb9-1ee608ab07fc", "metadata": {}, "source": ["#### 2.1.2 \u7b2c\u4e00\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "code", "execution_count": null, "id": "99e48462-7a92-4842-bdaa-2a478ba2252c", "metadata": {}, "outputs": [], "source": ["conversation.predict(input=\"\u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\")"]}, {"cell_type": "markdown", "id": "979d320b-6b20-4722-99db-c48a43711d6c", "metadata": {}, "source": ["#### 2.1.3 \u7b2c\u4e8c\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "code", "execution_count": 34, "id": "6ed6e97a-d7ea-4188-a6d7-f91d2a29d14a", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\n", "AI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\n", "Human: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'1+1\u7b49\u4e8e2\u3002'"]}, "execution_count": 34, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"1+1\u7b49\u4e8e\u591a\u5c11\uff1f\")"]}, {"cell_type": "markdown", "id": "8a1fd531-216e-42d8-b226-839747ad7dd3", "metadata": {}, "source": ["#### 2.1.4 \u7b2c\u4e09\u8f6e\u5bf9\u8bdd"]}, {"cell_type": "code", "execution_count": null, "id": "b5dfe488-2758-42c7-9c20-e483b4c22ab8", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\n", "AI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\n", "Human: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\n", "AI: 1+1\u7b49\u4e8e2\u3002\n", "Human: What is my name?\n", "AI: \u4f60\u7684\u540d\u5b57\u662f\u76ae\u76ae\u9c81\u3002\n", "Human: \u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'\u4f60\u53eb\u76ae\u76ae\u9c81\u3002'"]}, "execution_count": 36, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\")"]}, {"cell_type": "markdown", "id": "05d9822e-943d-4905-a1f8-a0d28c215d60", "metadata": {}, "source": ["#### 2.1.5 \u67e5\u770b\u50a8\u5b58\u7f13\u5b58"]}, {"cell_type": "code", "execution_count": 37, "id": "0795580f-b6b6-47e0-8882-26fe204560bd", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\n", "AI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\n", "Human: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\n", "AI: 1+1\u7b49\u4e8e2\u3002\n", "Human: What is my name?\n", "AI: \u4f60\u7684\u540d\u5b57\u662f\u76ae\u76ae\u9c81\u3002\n", "Human: \u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\n", "AI: \u4f60\u53eb\u76ae\u76ae\u9c81\u3002\n"]}], "source": ["print(memory.buffer) "]}, {"cell_type": "code", "execution_count": 38, "id": "dfe7824f-bd6e-4b95-92e2-1c85c62a92e9", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\n", "AI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\n", "Human: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\n", "AI: 1+1\u7b49\u4e8e2\u3002\n", "Human: What is my name?\n", "AI: \u4f60\u7684\u540d\u5b57\u662f\u76ae\u76ae\u9c81\u3002\n", "Human: \u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\n", "AI: \u4f60\u53eb\u76ae\u76ae\u9c81\u3002\n"]}], "source": ["print(memory.buffer) "]}, {"cell_type": "code", "execution_count": 39, "id": "48942759-8afb-4aed-80c5-a48952a2b0c0", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["{'history': 'Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\\nAI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\\nHuman: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\\nAI: 1+1\u7b49\u4e8e2\u3002\\nHuman: What is my name?\\nAI: \u4f60\u7684\u540d\u5b57\u662f\u76ae\u76ae\u9c81\u3002\\nHuman: \u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\\nAI: \u4f60\u53eb\u76ae\u76ae\u9c81\u3002'}\n"]}], "source": ["print(memory.load_memory_variables({}))"]}, {"cell_type": "code", "execution_count": 40, "id": "4d0c4625-e928-45dc-b8da-4ab865ac5f7e", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: \u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\\nAI: \u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\\nHuman: 1+1\u7b49\u4e8e\u591a\u5c11\uff1f\\nAI: 1+1\u7b49\u4e8e2\u3002\\nHuman: What is my name?\\nAI: \u4f60\u7684\u540d\u5b57\u662f\u76ae\u76ae\u9c81\u3002\\nHuman: \u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\\nAI: \u4f60\u53eb\u76ae\u76ae\u9c81\u3002'}"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "80f3778e-5fbf-43ed-9df1-d57d98ec6fb0", "metadata": {}, "source": ["#### 2.1.6 \u76f4\u63a5\u6dfb\u52a0\u5185\u5bb9\u5230\u50a8\u5b58\u7f13\u5b58"]}, {"cell_type": "code", "execution_count": 42, "id": "147b2c30-1662-4b49-aaf8-c228428e5cc6", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: \u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\\nAI: \u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f'}"]}, "execution_count": 42, "metadata": {}, "output_type": "execute_result"}], "source": ["memory = ConversationBufferMemory()\n", "memory.save_context({\"input\": \"\u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\"}, {\"output\": \"\u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f\"})\n", "memory.load_memory_variables({})"]}, {"cell_type": "code", "execution_count": 43, "id": "6b5e27f0-dad7-41b6-9326-bebf6299638f", "metadata": {"height": 64}, "outputs": [], "source": ["memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})"]}, {"cell_type": "code", "execution_count": 44, "id": "cfa7c555-06ab-4906-b3dc-906f789e08f5", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: \u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\\nAI: \u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f\\nHuman: Not much, just hanging\\nAI: Cool'}"]}, "execution_count": 44, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.load_memory_variables({})"]}, {"cell_type": "code", "execution_count": 45, "id": "deb33de8-37ea-4180-a73e-0fc456b14eb0", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: \u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\\nAI: \u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f\\nHuman: Not much, just hanging\\nAI: Cool\\nHuman: \u5f88\u9ad8\u5174\u548c\u4f60\u6210\u4e3a\u670b\u53cb\uff01\\nAI: \u662f\u7684\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u53bb\u5192\u9669\u5427\uff01'}"]}, "execution_count": 45, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.save_context({\"input\": \"\u5f88\u9ad8\u5174\u548c\u4f60\u6210\u4e3a\u670b\u53cb\uff01\"}, {\"output\": \"\u662f\u7684\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u53bb\u5192\u9669\u5427\uff01\"})\n", "memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "10146f1a-0114-4902-8122-d19ae6f7c461", "metadata": {}, "source": ["### 2.3 \u603b\u7ed3"]}, {"cell_type": "markdown", "id": "2759b6bc-edb2-4cfe-b0f8-1bf6c4d796f9", "metadata": {}, "source": ["\u5f53\u6211\u4eec\u5728\u4f7f\u7528\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u804a\u5929\u5bf9\u8bdd\u65f6\uff0c**\u5927\u578b\u8bed\u8a00\u6a21\u578b\u672c\u8eab\u5b9e\u9645\u4e0a\u662f\u65e0\u72b6\u6001\u7684\u3002\u8bed\u8a00\u6a21\u578b\u672c\u8eab\u5e76\u4e0d\u8bb0\u5f97\u5230\u76ee\u524d\u4e3a\u6b62\u7684\u5386\u53f2\u5bf9\u8bdd**\u3002\u6bcf\u6b21\u8c03\u7528API\u7ed3\u70b9\u90fd\u662f\u72ec\u7acb\u7684\u3002\u50a8\u5b58(Memory)\u53ef\u4ee5\u50a8\u5b58\u5230\u76ee\u524d\u4e3a\u6b62\u7684\u6240\u6709\u672f\u8bed\u6216\u5bf9\u8bdd\uff0c\u5e76\u5c06\u5176\u8f93\u5165\u6216\u9644\u52a0\u4e0a\u4e0b\u6587\u5230LLM\u4e2d\u7528\u4e8e\u751f\u6210\u8f93\u51fa\u3002\u5982\u6b64\u770b\u8d77\u6765\u5c31\u597d\u50cf\u5b83\u5728\u8fdb\u884c\u4e0b\u4e00\u8f6e\u5bf9\u8bdd\u7684\u65f6\u5019\uff0c\u8bb0\u5f97\u4e4b\u524d\u8bf4\u8fc7\u4ec0\u4e48\u3002\n"]}, {"cell_type": "markdown", "id": "cf98e9ff", "metadata": {}, "source": ["## \u4e09\u3001\u5bf9\u8bdd\u7f13\u5b58\u7a97\u53e3\u50a8\u5b58\n", " \n", "\u968f\u7740\u5bf9\u8bdd\u53d8\u5f97\u8d8a\u6765\u8d8a\u957f\uff0c\u6240\u9700\u7684\u5185\u5b58\u91cf\u4e5f\u53d8\u5f97\u975e\u5e38\u957f\u3002\u5c06\u5927\u91cf\u7684tokens\u53d1\u9001\u5230LLM\u7684\u6210\u672c\uff0c\u4e5f\u4f1a\u53d8\u5f97\u66f4\u52a0\u6602\u8d35,\u8fd9\u4e5f\u5c31\u662f\u4e3a\u4ec0\u4e48API\u7684\u8c03\u7528\u8d39\u7528\uff0c\u901a\u5e38\u662f\u57fa\u4e8e\u5b83\u9700\u8981\u5904\u7406\u7684tokens\u6570\u91cf\u800c\u6536\u8d39\u7684\u3002\n", " \n", "\u9488\u5bf9\u4ee5\u4e0a\u95ee\u9898\uff0cLangChain\u4e5f\u63d0\u4f9b\u4e86\u51e0\u79cd\u65b9\u4fbf\u7684\u50a8\u5b58\u65b9\u5f0f\u6765\u4fdd\u5b58\u5386\u53f2\u5bf9\u8bdd\u3002\u5176\u4e2d\uff0c\u5bf9\u8bdd\u7f13\u5b58\u7a97\u53e3\u50a8\u5b58\u53ea\u4fdd\u7559\u4e00\u4e2a\u7a97\u53e3\u5927\u5c0f\u7684\u5bf9\u8bdd\u3002\u5b83\u53ea\u4f7f\u7528\u6700\u8fd1\u7684n\u6b21\u4ea4\u4e92\u3002\u8fd9\u53ef\u4ee5\u7528\u4e8e\u4fdd\u6301\u6700\u8fd1\u4ea4\u4e92\u7684\u6ed1\u52a8\u7a97\u53e3\uff0c\u4ee5\u4fbf\u7f13\u51b2\u533a\u4e0d\u4f1a\u8fc7\u5927"]}, {"cell_type": "markdown", "id": "b63c9061-9916-4524-b497-93a0aa2b7d06", "metadata": {}, "source": ["### 3.1 \u82f1\u6587\u7248"]}, {"cell_type": "markdown", "id": "641477a4", "metadata": {}, "source": ["#### 3.1.1 \u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58"]}, {"cell_type": "code", "execution_count": 65, "id": "3ea6233e", "metadata": {"height": 47}, "outputs": [], "source": ["from langchain.memory import ConversationBufferWindowMemory\n", "\n", "# k \u4e3a\u7a97\u53e3\u53c2\u6570\uff0ck=1\u8868\u660e\u53ea\u4fdd\u7559\u4e00\u4e2a\u5bf9\u8bdd\u8bb0\u5fc6\n", "memory = ConversationBufferWindowMemory(k=1) "]}, {"cell_type": "code", "execution_count": 66, "id": "dc4553fb", "metadata": {"height": 115}, "outputs": [], "source": ["# \u5411memory\u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\n", "memory.save_context({\"input\": \"Hi\"}, {\"output\": \"What's up\"})\n", "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})"]}, {"cell_type": "code", "execution_count": 67, "id": "6a788403", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: Not much, just hanging\\nAI: Cool'}"]}, "execution_count": 67, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u5e76\u67e5\u770b\u8bb0\u5fc6\u53d8\u91cf\u5f53\u524d\u7684\u8bb0\u5f55\n", "memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "63bda148", "metadata": {}, "source": ["#### 3.1.2 \u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58"]}, {"cell_type": "code", "execution_count": 68, "id": "4087bc87", "metadata": {"height": 133}, "outputs": [], "source": ["llm = ChatOpenAI(temperature=0.0)\n", "memory = ConversationBufferWindowMemory(k=1)\n", "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )"]}, {"cell_type": "markdown", "id": "b6d661e3", "metadata": {}, "source": ["\u6ce8\u610f\u6b64\u5904\uff01\u7531\u4e8e\u8fd9\u91cc\u7528\u7684\u662f\u4e00\u4e2a\u7a97\u53e3\u7684\u8bb0\u5fc6\uff0c\u56e0\u6b64\u53ea\u80fd\u4fdd\u5b58\u4e00\u8f6e\u7684\u5386\u53f2\u6d88\u606f\uff0c\u56e0\u6b64AI\u5e76\u4e0d\u80fd\u77e5\u9053\u4f60\u7b2c\u4e00\u8f6e\u5bf9\u8bdd\u4e2d\u63d0\u5230\u7684\u540d\u5b57\uff0c\u4ed6\u6700\u591a\u53ea\u80fd\u8bb0\u4f4f\u4e0a\u4e00\u8f6e\uff08\u7b2c\u4e8c\u8f6e\uff09\u7684\u5bf9\u8bdd\u4fe1\u606f"]}, {"cell_type": "code", "execution_count": 69, "id": "4faaa952", "metadata": {"height": 47}, "outputs": [{"data": {"text/plain": ["\"Hello Andrew! It's nice to meet you. How can I assist you today?\""]}, "execution_count": 69, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"Hi, my name is Andrew\")"]}, {"cell_type": "code", "execution_count": 70, "id": "bb20ddaa", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["'1+1 is equal to 2.'"]}, "execution_count": 70, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"What is 1+1?\")"]}, {"cell_type": "code", "execution_count": 71, "id": "489b2194", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["\"I'm sorry, but I don't have access to personal information.\""]}, "execution_count": 71, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"What is my name?\")"]}, {"cell_type": "markdown", "id": "88837e7c-cf4b-469e-b820-bbfc49ba876c", "metadata": {}, "source": ["### 3.2 \u4e2d\u6587\u7248"]}, {"cell_type": "markdown", "id": "760ec3ad-6959-4a36-b1b5-4fcafe8088ad", "metadata": {}, "source": ["#### 3.1.1 \u6dfb\u52a0\u4e24\u8f6e\u5bf9\u8bdd\u5230\u7a97\u53e3\u50a8\u5b58"]}, {"cell_type": "code", "execution_count": 72, "id": "68a2907c", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'history': 'Human: \u5f88\u9ad8\u5174\u548c\u4f60\u6210\u4e3a\u670b\u53cb\uff01\\nAI: \u662f\u7684\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u53bb\u5192\u9669\u5427\uff01'}"]}, "execution_count": 72, "metadata": {}, "output_type": "execute_result"}], "source": ["from langchain.memory import ConversationBufferWindowMemory\n", "\n", "# k=1\u8868\u660e\u53ea\u4fdd\u7559\u4e00\u4e2a\u5bf9\u8bdd\u8bb0\u5fc6\n", "memory = ConversationBufferWindowMemory(k=1) \n", "memory.save_context({\"input\": \"\u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\"}, {\"output\": \"\u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f\"})\n", "memory.save_context({\"input\": \"\u5f88\u9ad8\u5174\u548c\u4f60\u6210\u4e3a\u670b\u53cb\uff01\"}, {\"output\": \"\u662f\u7684\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u53bb\u5192\u9669\u5427\uff01\"})\n", "memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "dcabf017-5bfd-4904-9f06-388f994eddc9", "metadata": {}, "source": ["#### 3.1.2 \u5728\u5bf9\u8bdd\u94fe\u4e2d\u5e94\u7528\u7a97\u53e3\u50a8\u5b58"]}, {"cell_type": "code", "execution_count": 74, "id": "1ee854d9", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u4f60\u597d\uff0c\u76ae\u76ae\u9c81\uff01\u5f88\u9ad8\u5174\u8ba4\u8bc6\u4f60\u3002\u6211\u662f\u4e00\u4e2aAI\u52a9\u624b\uff0c\u53ef\u4ee5\u56de\u7b54\u4f60\u7684\u95ee\u9898\u548c\u63d0\u4f9b\u5e2e\u52a9\u3002\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u4f60\u7684\u5417\uff1f\n", "1+1\u7b49\u4e8e2\u3002\n", "\u5f88\u62b1\u6b49\uff0c\u6211\u65e0\u6cd5\u77e5\u9053\u60a8\u7684\u540d\u5b57\u3002\n"]}], "source": ["llm = ChatOpenAI(temperature=0.0)\n", "memory = ConversationBufferWindowMemory(k=1)\n", "conversation = ConversationChain(llm=llm, memory=memory, verbose=False )\n", "print(conversation.predict(input=\"\u4f60\u597d, \u6211\u53eb\u76ae\u76ae\u9c81\"))\n", "print(conversation.predict(input=\"1+1\u7b49\u4e8e\u591a\u5c11\uff1f\"))\n", "print(conversation.predict(input=\"\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f\"))"]}, {"cell_type": "markdown", "id": "d2931b92", "metadata": {}, "source": ["## \u56db\u3001\u5bf9\u8bddtoken\u7f13\u5b58\u50a8\u5b58"]}, {"cell_type": "markdown", "id": "dff5b4c7", "metadata": {}, "source": ["\u4f7f\u7528\u5bf9\u8bddtoken\u7f13\u5b58\u8bb0\u5fc6\uff0c\u5185\u5b58\u5c06\u9650\u5236\u4fdd\u5b58\u7684token\u6570\u91cf\u3002\u5982\u679ctoken\u6570\u91cf\u8d85\u51fa\u6307\u5b9a\u6570\u76ee\uff0c\u5b83\u4f1a\u5207\u6389\u8fd9\u4e2a\u5bf9\u8bdd\u7684\u65e9\u671f\u90e8\u5206\n", "\u4ee5\u4fdd\u7559\u4e0e\u6700\u8fd1\u7684\u4ea4\u6d41\u76f8\u5bf9\u5e94\u7684token\u6570\u91cf\uff0c\u4f46\u4e0d\u8d85\u8fc7token\u9650\u5236\u3002"]}, {"cell_type": "code", "execution_count": 76, "id": "9f6d063c", "metadata": {"height": 31}, "outputs": [], "source": ["!pip install -q tiktoken "]}, {"cell_type": "code", "execution_count": 77, "id": "fb9020ed", "metadata": {"height": 81}, "outputs": [], "source": ["from langchain.llms import OpenAI\n", "from langchain.memory import ConversationTokenBufferMemory"]}, {"cell_type": "markdown", "id": "f3a84112", "metadata": {}, "source": ["### 4.1 \u82f1\u6587\u7248\n", "\u6dfb\u52a0\u5bf9\u8bdd\u5230Token\u7f13\u5b58\u50a8\u5b58,\u9650\u5236token\u6570\u91cf\uff0c\u8fdb\u884c\u6d4b\u8bd5"]}, {"cell_type": "code", "execution_count": 78, "id": "43582ee6", "metadata": {"height": 149}, "outputs": [], "source": ["memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", "memory.save_context({\"input\": \"AI is what?!\"}, {\"output\": \"Amazing!\"})\n", "memory.save_context({\"input\": \"Backpropagation is what?\"}, {\"output\": \"Beautiful!\"})\n", "memory.save_context({\"input\": \"Chatbots are what?\"}, {\"output\": \"Charming!\"})"]}, {"cell_type": "code", "execution_count": 79, "id": "284288e1", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["{'history': 'AI: Beautiful!\\nHuman: Chatbots are what?\\nAI: Charming!'}"]}, "execution_count": 79, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "7b62b2e1", "metadata": {}, "source": ["\u53ef\u4ee5\u770b\u5230\u524d\u9762\u8d85\u51fa\u7684\u7684token\u5df2\u7ecf\u88ab\u820d\u5f03\u4e86\uff01\uff01\uff01"]}, {"cell_type": "markdown", "id": "f7f6be43", "metadata": {}, "source": ["### 4.2 \u4e2d\u6587\u7248"]}, {"cell_type": "code", "execution_count": 80, "id": "e9191020", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'history': 'AI: \u8f7b\u821f\u5df2\u8fc7\u4e07\u91cd\u5c71\u3002'}"]}, "execution_count": 80, "metadata": {}, "output_type": "execute_result"}], "source": ["memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)\n", "memory.save_context({\"input\": \"\u671d\u8f9e\u767d\u5e1d\u5f69\u4e91\u95f4\uff0c\"}, {\"output\": \"\u5343\u91cc\u6c5f\u9675\u4e00\u65e5\u8fd8\u3002\"})\n", "memory.save_context({\"input\": \"\u4e24\u5cb8\u733f\u58f0\u557c\u4e0d\u4f4f\uff0c\"}, {\"output\": \"\u8f7b\u821f\u5df2\u8fc7\u4e07\u91cd\u5c71\u3002\"})\n", "memory.load_memory_variables({})"]}, {"cell_type": "markdown", "id": "fb08ef4a-876f-422a-81f9-4805288e5955", "metadata": {}, "source": ["### 4.3 \u8865\u5145"]}, {"cell_type": "markdown", "id": "5e4d918b", "metadata": {}, "source": ["ChatGPT\u4f7f\u7528\u4e00\u79cd\u57fa\u4e8e\u5b57\u8282\u5bf9\u7f16\u7801\uff08Byte Pair Encoding\uff0cBPE\uff09\u7684\u65b9\u6cd5\u6765\u8fdb\u884ctokenization\uff08\u5c06\u8f93\u5165\u6587\u672c\u62c6\u5206\u4e3atoken\uff09\u3002BPE\u662f\u4e00\u79cd\u5e38\u89c1\u7684tokenization\u6280\u672f\uff0c\u5b83\u5c06\u8f93\u5165\u6587\u672c\u5206\u5272\u6210\u8f83\u5c0f\u7684\u5b50\u8bcd\u5355\u5143\u3002 \n", "\n", "OpenAI\u5728\u5176\u5b98\u65b9GitHub\u4e0a\u516c\u5f00\u4e86\u4e00\u4e2a\u6700\u65b0\u7684\u5f00\u6e90Python\u5e93 [tiktoken](https://github.com/openai/tiktoken)\uff0c\u8fd9\u4e2a\u5e93\u4e3b\u8981\u662f\u7528\u6765\u8ba1\u7b97tokens\u6570\u91cf\u7684\u3002\u76f8\u6bd4\u8f83HuggingFace\u7684tokenizer\uff0c\u5176\u901f\u5ea6\u63d0\u5347\u4e86\u597d\u51e0\u500d\u3002\n", "\n", "\u5177\u4f53token\u8ba1\u7b97\u65b9\u5f0f,\u7279\u522b\u662f\u6c49\u5b57\u548c\u82f1\u6587\u5355\u8bcd\u7684token\u533a\u522b\uff0c\u5177\u4f53\u8bfe\u53c2\u8003[\u77e5\u4e4e\u6587\u7ae0](https://www.zhihu.com/question/594159910) \u3002"]}, {"cell_type": "markdown", "id": "5ff55d5d", "metadata": {}, "source": ["## \u4e94\u3001\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58"]}, {"cell_type": "markdown", "id": "7d39b83a", "metadata": {}, "source": ["\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\uff0c**\u4f7f\u7528LLM\u7f16\u5199\u5230\u76ee\u524d\u4e3a\u6b62\u5386\u53f2\u5bf9\u8bdd\u7684\u6458\u8981**\uff0c\u5e76\u5c06\u5176\u4fdd\u5b58"]}, {"cell_type": "code", "execution_count": 82, "id": "72dcf8b1", "metadata": {"height": 64}, "outputs": [], "source": ["from langchain.chains import ConversationChain\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain.memory import ConversationSummaryBufferMemory"]}, {"cell_type": "markdown", "id": "243b213e-ce17-46a0-8652-03658ca58dd8", "metadata": {}, "source": ["### 5.1 \u82f1\u6587\u7248"]}, {"cell_type": "markdown", "id": "6572ef39", "metadata": {}, "source": ["#### 5.1.1 \u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\n", "\n", "\u521b\u5efa\u4e00\u4e2a\u957f\u5b57\u7b26\u4e32\uff0c\u5176\u4e2d\u5305\u542b\u67d0\u4eba\u7684\u65e5\u7a0b\u5b89\u6392"]}, {"cell_type": "code", "execution_count": 84, "id": "4a5b238f", "metadata": {"height": 285}, "outputs": [], "source": ["# \u521b\u5efa\u4e00\u4e2a\u957f\u5b57\u7b26\u4e32\n", "schedule = \"There is a meeting at 8am with your product team. \\\n", "You will need your powerpoint presentation prepared. \\\n", "9am-12pm have time to work on your LangChain \\\n", "project which will go quickly because Langchain is such a powerful tool. \\\n", "At Noon, lunch at the italian resturant with a customer who is driving \\\n", "from over an hour away to meet you to understand the latest in AI. \\\n", "Be sure to bring your laptop to show the latest LLM demo.\"\n", "\n", "# \u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u8bb0\u5fc6\n", "llm = ChatOpenAI(temperature=0.0)\n", "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100) \n", "memory.save_context({\"input\": \"Hello\"}, {\"output\": \"What's up\"})\n", "memory.save_context({\"input\": \"Not much, just hanging\"}, {\"output\": \"Cool\"})\n", "memory.save_context(\n", " {\"input\": \"What is on the schedule today?\"}, {\"output\": f\"{schedule}\"}\n", ")"]}, {"cell_type": "code", "execution_count": 89, "id": "15226a41-ab36-43a0-93f7-c03c6b374936", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n"]}], "source": ["print(memory.load_memory_variables({})['history'])"]}, {"cell_type": "markdown", "id": "7ccb97b6", "metadata": {}, "source": ["#### 5.1.2 \u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe\n", "\u57fa\u4e8e\u4e0a\u9762\u7684\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\uff0c\u65b0\u5efa\u4e00\u4e2a\u5bf9\u8bdd\u94fe"]}, {"cell_type": "code", "execution_count": 90, "id": "6728edba", "metadata": {"height": 99}, "outputs": [], "source": ["conversation = ConversationChain(llm=llm, memory=memory, verbose=True)"]}, {"cell_type": "code", "execution_count": 91, "id": "9a221b1d", "metadata": {"height": 47}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting.\n", "Human: What would be a good demo to show?\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.'"]}, "execution_count": 91, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"What would be a good demo to show?\")"]}, {"cell_type": "code", "execution_count": 92, "id": "bb582617", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["System: The human and AI exchange greetings. The human asks about the schedule for the day. The AI provides a detailed schedule, including a meeting with the product team, work on the LangChain project, and a lunch meeting with a customer interested in AI. The AI emphasizes the importance of bringing a laptop to showcase the latest LLM demo during the lunch meeting. A good demo to show during the lunch meeting with the customer interested in AI would be the latest LLM (Language Model) demo. The LLM is a cutting-edge AI model that can generate human-like text based on a given prompt. It has been trained on a vast amount of data and can generate coherent and contextually relevant responses. By showcasing the LLM demo, you can demonstrate the capabilities of AI in natural language processing and how it can be applied to various industries and use cases.\n"]}], "source": ["print(memory.load_memory_variables({})['history'])"]}, {"cell_type": "markdown", "id": "4ba827aa", "metadata": {"height": 31}, "source": ["### 5.2 \u4e2d\u6587\u7248"]}, {"cell_type": "markdown", "id": "64898f33-c538-4e68-b008-7123870b692b", "metadata": {}, "source": ["#### 5.2.1 \u4f7f\u7528\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\n", "\n", "\u521b\u5efa\u4e00\u4e2a\u957f\u5b57\u7b26\u4e32\uff0c\u5176\u4e2d\u5305\u542b\u67d0\u4eba\u7684\u65e5\u7a0b\u5b89\u6392"]}, {"cell_type": "code", "execution_count": 97, "id": "2c07922b", "metadata": {"height": 31}, "outputs": [], "source": ["# \u521b\u5efa\u4e00\u4e2a\u957f\u5b57\u7b26\u4e32\n", "schedule = \"\u5728\u516b\u70b9\u4f60\u548c\u4f60\u7684\u4ea7\u54c1\u56e2\u961f\u6709\u4e00\u4e2a\u4f1a\u8bae\u3002 \\\n", "\u4f60\u9700\u8981\u505a\u4e00\u4e2aPPT\u3002 \\\n", "\u4e0a\u53489\u70b9\u523012\u70b9\u4f60\u9700\u8981\u5fd9\u4e8eLangChain\u3002\\\n", "Langchain\u662f\u4e00\u4e2a\u6709\u7528\u7684\u5de5\u5177\uff0c\u56e0\u6b64\u4f60\u7684\u9879\u76ee\u8fdb\u5c55\u7684\u975e\u5e38\u5feb\u3002\\\n", "\u4e2d\u5348\uff0c\u5728\u610f\u5927\u5229\u9910\u5385\u4e0e\u4e00\u4f4d\u5f00\u8f66\u6765\u7684\u987e\u5ba2\u5171\u8fdb\u5348\u9910 \\\n", "\u8d70\u4e86\u4e00\u4e2a\u591a\u5c0f\u65f6\u7684\u8def\u7a0b\u4e0e\u4f60\u89c1\u9762\uff0c\u53ea\u4e3a\u4e86\u89e3\u6700\u65b0\u7684 AI\u3002 \\\n", "\u786e\u4fdd\u4f60\u5e26\u4e86\u7b14\u8bb0\u672c\u7535\u8111\u53ef\u4ee5\u5c55\u793a\u6700\u65b0\u7684 LLM \u6837\u4f8b.\"\n", "\n", "llm = ChatOpenAI(temperature=0.0)\n", "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)\n", "memory.save_context({\"input\": \"\u4f60\u597d\uff0c\u6211\u53eb\u76ae\u76ae\u9c81\"}, {\"output\": \"\u4f60\u597d\u554a\uff0c\u6211\u53eb\u9c81\u897f\u897f\"})\n", "memory.save_context({\"input\": \"\u5f88\u9ad8\u5174\u548c\u4f60\u6210\u4e3a\u670b\u53cb\uff01\"}, {\"output\": \"\u662f\u7684\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u53bb\u5192\u9669\u5427\uff01\"})\n", "memory.save_context({\"input\": \"\u4eca\u5929\u7684\u65e5\u7a0b\u5b89\u6392\u662f\u4ec0\u4e48\uff1f\"}, {\"output\": f\"{schedule}\"})"]}, {"cell_type": "code", "execution_count": 98, "id": "17424a12-430f-4529-9067-300978c6169e", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n"]}], "source": ["print(memory.load_memory_variables({})['history'])"]}, {"cell_type": "markdown", "id": "9e29a956-607a-4247-9eb5-01285a370991", "metadata": {}, "source": ["#### 5.1.2 \u57fa\u4e8e\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\u7684\u5bf9\u8bdd\u94fe\n", "\u57fa\u4e8e\u4e0a\u9762\u7684\u5bf9\u8bdd\u6458\u8981\u7f13\u5b58\u50a8\u5b58\uff0c\u65b0\u5efa\u4e00\u4e2a\u5bf9\u8bdd\u94fe"]}, {"cell_type": "code", "execution_count": 99, "id": "52696c8c", "metadata": {"height": 31}, "outputs": [], "source": ["conversation = ConversationChain(llm=llm, memory=memory, verbose=True)"]}, {"cell_type": "code", "execution_count": 100, "id": "48690d13", "metadata": {"height": 31}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "\n", "\u001b[1m> Entering new chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples.\n", "Human: \u5c55\u793a\u4ec0\u4e48\u6837\u7684\u6837\u4f8b\u6700\u597d\u5462\uff1f\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n"]}, {"data": {"text/plain": ["'\u5c55\u793a\u4e00\u4e9b\u5177\u6709\u591a\u6837\u6027\u548c\u521b\u65b0\u6027\u7684\u6837\u4f8b\u53ef\u80fd\u662f\u6700\u597d\u7684\u9009\u62e9\u3002\u4f60\u53ef\u4ee5\u9009\u62e9\u5c55\u793a\u4e00\u4e9b\u57fa\u4e8e\u56fe\u50cf\u8bc6\u522b\u7684\u6837\u4f8b\uff0c\u6bd4\u5982\u4eba\u8138\u8bc6\u522b\u3001\u7269\u4f53\u8bc6\u522b\u7b49\u3002\u53e6\u5916\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5c55\u793a\u4e00\u4e9b\u81ea\u7136\u8bed\u8a00\u5904\u7406\u65b9\u9762\u7684\u6837\u4f8b\uff0c\u6bd4\u5982\u6587\u672c\u751f\u6210\u3001\u60c5\u611f\u5206\u6790\u7b49\u3002\u6700\u91cd\u8981\u7684\u662f\u9009\u62e9\u90a3\u4e9b\u80fd\u591f\u5c55\u793a\u51fa\u4f60\u4eec\u56e2\u961f\u7684\u6280\u672f\u5b9e\u529b\u548c\u521b\u9020\u529b\u7684\u6837\u4f8b\u3002'"]}, "execution_count": 100, "metadata": {}, "output_type": "execute_result"}], "source": ["conversation.predict(input=\"\u5c55\u793a\u4ec0\u4e48\u6837\u7684\u6837\u4f8b\u6700\u597d\u5462\uff1f\")"]}, {"cell_type": "code", "execution_count": 101, "id": "85bba1f8", "metadata": {"height": 31}, "outputs": [{"data": {"text/plain": ["{'history': \"System: The human introduces themselves as Pipilu and the AI introduces themselves as Luxixi. They express happiness at becoming friends and decide to go on an adventure together. The human asks about the schedule for the day. The AI informs them that they have a meeting with their product team at 8 o'clock and need to prepare a PowerPoint presentation. From 9 am to 12 pm, they will be busy with LangChain, a useful tool that helps their project progress quickly. At noon, they will have lunch with a customer who has driven for over an hour just to learn about the latest AI. The AI advises the human to bring their laptop to showcase the latest LLM samples. The human asks what kind of samples would be best to showcase. The AI suggests that showcasing diverse and innovative samples would be the best choice. They recommend selecting samples based on image recognition, such as face recognition and object recognition. Additionally, they suggest showcasing samples related to natural language processing, such as text generation and sentiment analysis. The AI emphasizes the importance of choosing samples that demonstrate the team's technical expertise and creativity.\"}"]}, "execution_count": 101, "metadata": {}, "output_type": "execute_result"}], "source": ["memory.load_memory_variables({}) # \u6458\u8981\u8bb0\u5f55\u66f4\u65b0\u4e86"]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12"}, "toc": {"base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": true}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file From d7dc7e44dc21ea0a8d1a4a917879efa3810641b3 Mon Sep 17 00:00:00 2001 From: joyenjoye\n", " OPENAI_API_KEY=\"your_api_key\" \n", "
\n", " \n", " \u66ff\u6362\"your_api_key\"\u4e3a\u4f60\u81ea\u5df1\u7684 API Key"]}, {"cell_type": "code", "execution_count": 1, "id": "adc3519c-4d12-4011-9223-2f3cb3c42b93", "metadata": {}, "outputs": [], "source": ["# \u4e0b\u8f7d\u9700\u8981\u7684\u5305python-dotenv\u548copenai\n", "# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "!pip install -q python-dotenv\n", "!pip install -q openai"]}, {"cell_type": "code", "execution_count": 2, "id": "1ad53241-bef6-42b8-894b-bcbbc8c64df7", "metadata": {"tags": []}, "outputs": [], "source": ["import os\n", "import openai\n", "from dotenv import load_dotenv, find_dotenv\n", "\n", "# \u8bfb\u53d6\u672c\u5730/\u9879\u76ee\u7684\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "# find_dotenv()\u5bfb\u627e\u5e76\u5b9a\u4f4d.env\u6587\u4ef6\u7684\u8def\u5f84\n", "# load_dotenv()\u8bfb\u53d6\u8be5.env\u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u5230\u5f53\u524d\u7684\u8fd0\u884c\u73af\u5883\u4e2d \n", "# \u5982\u679c\u4f60\u8bbe\u7f6e\u7684\u662f\u5168\u5c40\u7684\u73af\u5883\u53d8\u91cf\uff0c\u8fd9\u884c\u4ee3\u7801\u5219\u6ca1\u6709\u4efb\u4f55\u4f5c\u7528\u3002\n", "_ = load_dotenv(find_dotenv())\n", "\n", "# \u83b7\u53d6\u73af\u5883\u53d8\u91cf OPENAI_API_KEY\n", "openai.api_key = os.environ['OPENAI_API_KEY'] "]}, {"cell_type": "markdown", "id": "b940ce7c", "metadata": {"tags": []}, "source": ["## \u4e8c\u3001LLMChain"]}, {"cell_type": "markdown", "id": "e000bd16", "metadata": {}, "source": ["LLMChain\u662f\u4e00\u4e2a\u7b80\u5355\u4f46\u975e\u5e38\u5f3a\u5927\u7684\u94fe\uff0c\u4e5f\u662f\u540e\u9762\u6211\u4eec\u5c06\u8981\u4ecb\u7ecd\u7684\u8bb8\u591a\u94fe\u7684\u57fa\u7840\u3002"]}, {"cell_type": "code", "execution_count": 3, "id": "b84e441b", "metadata": {}, "outputs": [], "source": ["#!pip install pandas"]}, {"cell_type": "code", "execution_count": 46, "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", "metadata": {}, "outputs": [], "source": ["import pandas as pd\n", "df = pd.read_csv('Data.csv')"]}, {"cell_type": "code", "execution_count": 47, "id": "b7a09c35", "metadata": {}, "outputs": [{"data": {"text/html": ["| \n", " | Product | \n", "Review | \n", "
|---|---|---|
| 0 | \n", "Queen Size Sheet Set | \n", "I ordered a king size set. My only criticism w... | \n", "
| 1 | \n", "Waterproof Phone Pouch | \n", "I loved the waterproof sac, although the openi... | \n", "
| 2 | \n", "Luxury Air Mattress | \n", "This mattress had a small hole in the top of i... | \n", "
| 3 | \n", "Pillows Insert | \n", "This is the best throw pillow fillers on Amazo... | \n", "
| 4 | \n", "Milk Frother Handheld\\n | \n", "I loved this product. But they only seem to l... | \n", "
\n", + " OPENAI_API_KEY=\"your_api_key\" \n", + "
\n", + " \n", + " 替换\"your_api_key\"为你自己的 API Key" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "adc3519c-4d12-4011-9223-2f3cb3c42b93", + "metadata": {}, + "outputs": [], + "source": [ + "# 下载需要的包python-dotenv和openai\n", + "# 如果你需要查看安装过程日志,可删除 -q \n", + "!pip install -q python-dotenv\n", + "!pip install -q openai" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "1ad53241-bef6-42b8-894b-bcbbc8c64df7", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import os\n", + "import openai\n", + "from dotenv import load_dotenv, find_dotenv\n", + "\n", + "# 读取本地/项目的环境变量。\n", + "\n", + "# find_dotenv()寻找并定位.env文件的路径\n", + "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n", + "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ['OPENAI_API_KEY'] " + ] + }, + { + "cell_type": "markdown", + "id": "b940ce7c", + "metadata": { + "tags": [] + }, + "source": [ + "## 二、大语言模型链" + ] + }, + { + "cell_type": "markdown", + "id": "e000bd16", + "metadata": {}, + "source": [ + "大语言模型链(LLMChain)是一个简单但非常强大的链,也是后面我们将要介绍的许多链的基础。" + ] + }, + { + "cell_type": "markdown", + "id": "d57e93b9-52ba-4f86-a953-e4661b895a3d", + "metadata": {}, + "source": [ + "### 2.1 导入数据" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b84e441b", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q pandas" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "df = pd.read_csv('data/Data.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "b7a09c35", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "| \n", + " | Product | \n", + "Review | \n", + "
|---|---|---|
| 0 | \n", + "Queen Size Sheet Set | \n", + "I ordered a king size set. My only criticism w... | \n", + "
| 1 | \n", + "Waterproof Phone Pouch | \n", + "I loved the waterproof sac, although the openi... | \n", + "
| 2 | \n", + "Luxury Air Mattress | \n", + "This mattress had a small hole in the top of i... | \n", + "
| 3 | \n", + "Pillows Insert | \n", + "This is the best throw pillow fillers on Amazo... | \n", + "
| 4 | \n", + "Milk Frother Handheld\\n | \n", + "I loved this product. But they only seem to l... | \n", + "
\n", - " OPENAI_API_KEY=\"your_api_key\" \n", - "
\n", - " \n", - " 替换\"your_api_key\"为你自己的 API Key" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "adc3519c-4d12-4011-9223-2f3cb3c42b93", - "metadata": {}, - "outputs": [], - "source": [ - "# 下载需要的包python-dotenv和openai\n", - "# 如果你需要查看安装过程日志,可删除 -q \n", - "!pip install -q python-dotenv\n", - "!pip install -q openai" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "1ad53241-bef6-42b8-894b-bcbbc8c64df7", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import openai\n", - "from dotenv import load_dotenv, find_dotenv\n", - "\n", - "# 读取本地/项目的环境变量。\n", - "\n", - "# find_dotenv()寻找并定位.env文件的路径\n", - "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n", - "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", - "_ = load_dotenv(find_dotenv())\n", - "\n", - "# 获取环境变量 OPENAI_API_KEY\n", - "openai.api_key = os.environ['OPENAI_API_KEY'] " - ] - }, - { - "cell_type": "markdown", - "id": "b940ce7c", - "metadata": { - "tags": [] - }, - "source": [ - "## 二、大语言模型链" - ] - }, - { - "cell_type": "markdown", - "id": "e000bd16", - "metadata": {}, - "source": [ - "大语言模型链(LLMChain)是一个简单但非常强大的链,也是后面我们将要介绍的许多链的基础。" - ] - }, - { - "cell_type": "markdown", - "id": "d57e93b9-52ba-4f86-a953-e4661b895a3d", - "metadata": {}, - "source": [ - "### 2.1 导入数据" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b84e441b", - "metadata": {}, - "outputs": [], - "source": [ - "!pip install -q pandas" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "df = pd.read_csv('data/Data.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b7a09c35", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "| \n", - " | Product | \n", - "Review | \n", - "
|---|---|---|
| 0 | \n", - "Queen Size Sheet Set | \n", - "I ordered a king size set. My only criticism w... | \n", - "
| 1 | \n", - "Waterproof Phone Pouch | \n", - "I loved the waterproof sac, although the openi... | \n", - "
| 2 | \n", - "Luxury Air Mattress | \n", - "This mattress had a small hole in the top of i... | \n", - "
| 3 | \n", - "Pillows Insert | \n", - "This is the best throw pillow fillers on Amazo... | \n", - "
| 4 | \n", - "Milk Frother Handheld\\n | \n", - "I loved this product. But they only seem to l... | \n", - "
\n", " OPENAI_API_KEY=\"your_api_key\" \n", "
\n", " \n", " \u66ff\u6362\"your_api_key\"\u4e3a\u4f60\u81ea\u5df1\u7684 API Key"]}, {"cell_type": "code", "execution_count": 10, "id": "adc3519c-4d12-4011-9223-2f3cb3c42b93", "metadata": {}, "outputs": [], "source": ["# \u4e0b\u8f7d\u9700\u8981\u7684\u5305python-dotenv\u548copenai\n", "# \u5982\u679c\u4f60\u9700\u8981\u67e5\u770b\u5b89\u88c5\u8fc7\u7a0b\u65e5\u5fd7\uff0c\u53ef\u5220\u9664 -q \n", "!pip install -q python-dotenv\n", "!pip install -q openai"]}, {"cell_type": "code", "execution_count": 11, "id": "1ad53241-bef6-42b8-894b-bcbbc8c64df7", "metadata": {"tags": []}, "outputs": [], "source": ["import os\n", "import openai\n", "from dotenv import load_dotenv, find_dotenv\n", "\n", "# \u8bfb\u53d6\u672c\u5730/\u9879\u76ee\u7684\u73af\u5883\u53d8\u91cf\u3002\n", "\n", "# find_dotenv()\u5bfb\u627e\u5e76\u5b9a\u4f4d.env\u6587\u4ef6\u7684\u8def\u5f84\n", "# load_dotenv()\u8bfb\u53d6\u8be5.env\u6587\u4ef6\uff0c\u5e76\u5c06\u5176\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u5230\u5f53\u524d\u7684\u8fd0\u884c\u73af\u5883\u4e2d \n", "# \u5982\u679c\u4f60\u8bbe\u7f6e\u7684\u662f\u5168\u5c40\u7684\u73af\u5883\u53d8\u91cf\uff0c\u8fd9\u884c\u4ee3\u7801\u5219\u6ca1\u6709\u4efb\u4f55\u4f5c\u7528\u3002\n", "_ = load_dotenv(find_dotenv())\n", "\n", "# \u83b7\u53d6\u73af\u5883\u53d8\u91cf OPENAI_API_KEY\n", "openai.api_key = os.environ['OPENAI_API_KEY'] "]}, {"cell_type": "markdown", "id": "b940ce7c", "metadata": {"tags": []}, "source": ["## \u4e8c\u3001\u5927\u8bed\u8a00\u6a21\u578b\u94fe"]}, {"cell_type": "markdown", "id": "e000bd16", "metadata": {}, "source": ["\u5927\u8bed\u8a00\u6a21\u578b\u94fe(LLMChain)\u662f\u4e00\u4e2a\u7b80\u5355\u4f46\u975e\u5e38\u5f3a\u5927\u7684\u94fe\uff0c\u4e5f\u662f\u540e\u9762\u6211\u4eec\u5c06\u8981\u4ecb\u7ecd\u7684\u8bb8\u591a\u94fe\u7684\u57fa\u7840\u3002"]}, {"cell_type": "markdown", "id": "d57e93b9-52ba-4f86-a953-e4661b895a3d", "metadata": {}, "source": ["### 2.1 \u5bfc\u5165\u6570\u636e"]}, {"cell_type": "code", "execution_count": 1, "id": "b84e441b", "metadata": {}, "outputs": [], "source": ["!pip install -q pandas"]}, {"cell_type": "code", "execution_count": 4, "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", "metadata": {}, "outputs": [], "source": ["import pandas as pd\n", "df = pd.read_csv('data/Data.csv')"]}, {"cell_type": "code", "execution_count": 5, "id": "b7a09c35", "metadata": {}, "outputs": [{"data": {"text/html": ["| \n", " | Product | \n", "Review | \n", "
|---|---|---|
| 0 | \n", "Queen Size Sheet Set | \n", "I ordered a king size set. My only criticism w... | \n", "
| 1 | \n", "Waterproof Phone Pouch | \n", "I loved the waterproof sac, although the openi... | \n", "
| 2 | \n", "Luxury Air Mattress | \n", "This mattress had a small hole in the top of i... | \n", "
| 3 | \n", "Pillows Insert | \n", "This is the best throw pillow fillers on Amazo... | \n", "
| 4 | \n", "Milk Frother Handheld\\n | \n", "I loved this product. But they only seem to l... | \n", "
\n"," OPENAI_API_KEY=\"your_api_key\" \n","
\n"," \n"," 替换\"your_api_key\"为你自己的 API Key"]},{"cell_type":"code","execution_count":1,"id":"cc33ceb1-535f-454d-988c-347a8b14fd72","metadata":{},"outputs":[],"source":["# 下载需要的包python-dotenv和openai\n","# 如果你需要查看安装过程日志,可删除 -q \n","!pip install -q python-dotenv\n","!pip install -q openai"]},{"cell_type":"code","execution_count":2,"id":"e3c97235-f101-47f2-92db-1c37f4bf9845","metadata":{"tags":[]},"outputs":[],"source":["import os\n","import openai\n","from dotenv import load_dotenv, find_dotenv\n","\n","# 读取本地/项目的环境变量。\n","\n","# find_dotenv()寻找并定位.env文件的路径\n","# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n","# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n","_ = load_dotenv(find_dotenv())\n","\n","# 获取环境变量 OPENAI_API_KEY\n","openai.api_key = os.environ['OPENAI_API_KEY'] "]},{"cell_type":"code","execution_count":52,"id":"af8c3c96","metadata":{},"outputs":[{"data":{"text/plain":["'\\n\\n人工智能是一项极具前景的技术,它的发展正在改变人类的生活方式,带来了无数的便利,也被认为是未来发展的重要标志。人工智能的发展让许多复杂的任务变得更加容易,更高效的完成,节省了大量的时间和精力,为人类发展带来了极大的帮助。'"]},"execution_count":52,"metadata":{},"output_type":"execute_result"}],"source":["from langchain.llms import OpenAI\n","\n","llm = OpenAI(model_name=\"text-davinci-003\",max_tokens=1024)\n","llm(\"怎么评价人工智能\")"]},{"cell_type":"markdown","id":"8cb7a7ec","metadata":{"height":30},"source":["## 一、导入embedding模型和向量存储组件\n","使用Dock Array内存搜索向量存储,作为一个内存向量存储,不需要连接外部数据库"]},{"cell_type":"code","execution_count":3,"id":"974acf8e-8f88-42de-88f8-40a82cb58e8b","metadata":{"height":98},"outputs":[],"source":["from langchain.chains import RetrievalQA #检索QA链,在文档上进行检索\n","from langchain.chat_models import ChatOpenAI #openai模型\n","from langchain.document_loaders import CSVLoader #文档加载器,采用csv格式存储\n","from langchain.vectorstores import DocArrayInMemorySearch #向量存储\n","from IPython.display import display, Markdown #在jupyter显示信息的工具"]},{"cell_type":"code","execution_count":4,"id":"7249846e","metadata":{"height":75},"outputs":[],"source":["#读取文件\n","file = 'OutdoorClothingCatalog_1000.csv'\n","loader = CSVLoader(file_path=file)"]},{"cell_type":"code","execution_count":24,"id":"7724f00e","metadata":{"height":30},"outputs":[{"data":{"text/html":["| \n"," | 0 | \n","1 | \n","2 | \n","
|---|---|---|---|
| 0 | \n","NaN | \n","name | \n","description | \n","
| 1 | \n","0.0 | \n","Women's Campside Oxfords | \n","This ultracomfortable lace-to-toe Oxford boast... | \n","
| 2 | \n","1.0 | \n","Recycled Waterhog Dog Mat, Chevron Weave | \n","Protect your floors from spills and splashing ... | \n","
| 3 | \n","2.0 | \n","Infant and Toddler Girls' Coastal Chill Swimsu... | \n","She'll love the bright colors, ruffles and exc... | \n","
| 4 | \n","3.0 | \n","Refresh Swimwear, V-Neck Tankini Contrasts | \n","Whether you're going for a swim or heading out... | \n","
| ... | \n","... | \n","... | \n","... | \n","
| 996 | \n","995.0 | \n","Men's Classic Denim, Standard Fit | \n","Crafted from premium denim that will last wash... | \n","
| 997 | \n","996.0 | \n","CozyPrint Sweater Fleece Pullover | \n","The ultimate sweater fleece - made from superi... | \n","
| 998 | \n","997.0 | \n","Women's NRS Endurance Spray Paddling Pants | \n","These comfortable and affordable splash paddli... | \n","
| 999 | \n","998.0 | \n","Women's Stop Flies Hoodie | \n","This great-looking hoodie uses No Fly Zone Tec... | \n","
| 1000 | \n","999.0 | \n","Modern Utility Bag | \n","This US-made crossbody bag is built with the s... | \n","
1001 rows × 3 columns
\n","\n", + " OPENAI_API_KEY=\"your_api_key\" \n", + "
\n", + " \n", + " 替换\"your_api_key\"为你自己的 API Key" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "cc33ceb1-535f-454d-988c-347a8b14fd72", + "metadata": {}, + "outputs": [], + "source": [ + "# 下载需要的包python-dotenv和openai\n", + "# 如果你需要查看安装过程日志,可删除 -q \n", + "!pip install -q python-dotenv\n", + "!pip install -q openai" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e3c97235-f101-47f2-92db-1c37f4bf9845", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import os\n", + "import openai\n", + "from dotenv import load_dotenv, find_dotenv\n", + "\n", + "# 读取本地/项目的环境变量。\n", + "\n", + "# find_dotenv()寻找并定位.env文件的路径\n", + "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n", + "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ['OPENAI_API_KEY'] " + ] + }, + { + "cell_type": "markdown", + "id": "8cb7a7ec", + "metadata": { + "height": 30 + }, + "source": [ + "## 一、直接" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "6fbf1fe4-411a-4d22-b362-ac8400fa31b9", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install --upgrade -q langchain\n", + "!pip install -q docarray" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "metadata": { + "height": 98 + }, + "outputs": [], + "source": [ + "from langchain.chains import RetrievalQA #检索QA链,在文档上进行检索\n", + "from langchain.chat_models import ChatOpenAI #openai模型\n", + "from langchain.document_loaders import CSVLoader #文档加载器,采用csv格式存储\n", + "from langchain.vectorstores import DocArrayInMemorySearch #向量存储\n", + "from IPython.display import display, Markdown #在jupyter显示信息的工具" + ] + }, + { + "cell_type": "markdown", + "id": "159206b6-46a8-47ee-99a8-13bf7d554da4", + "metadata": {}, + "source": [ + "### 1.1 导入数据" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7249846e", + "metadata": { + "height": 75 + }, + "outputs": [], + "source": [ + "file = 'data/OutdoorClothingCatalog_1000.csv'\n", + "loader = CSVLoader(file_path=file)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "7724f00e", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/html": [ + "| \n", + " | name | \n", + "description | \n", + "
|---|---|---|
| 0 | \n", + "Women's Campside Oxfords | \n", + "This ultracomfortable lace-to-toe Oxford boast... | \n", + "
| 1 | \n", + "Recycled Waterhog Dog Mat, Chevron Weave | \n", + "Protect your floors from spills and splashing ... | \n", + "
| 2 | \n", + "Infant and Toddler Girls' Coastal Chill Swimsu... | \n", + "She'll love the bright colors, ruffles and exc... | \n", + "
| 3 | \n", + "Refresh Swimwear, V-Neck Tankini Contrasts | \n", + "Whether you're going for a swim or heading out... | \n", + "
| 4 | \n", + "EcoFlex 3L Storm Pants | \n", + "Our new TEK O2 technology makes our four-seaso... | \n", + "