diff --git a/content/LangChain for LLM Application Development/2.模型、提示和解析器.ipynb b/content/LangChain for LLM Application Development/2.模型、提示和解析器.ipynb index 35a85ea..734ec03 100644 --- a/content/LangChain for LLM Application Development/2.模型、提示和解析器.ipynb +++ b/content/LangChain for LLM Application Development/2.模型、提示和解析器.ipynb @@ -1,51 +1,31 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "# 2. 模型,提示和输出解释器\n", + "# 模型,提示和输出解释器\n", "\n", - "\n", - "\n", - "\n", - "" + "\n", + "**目录**\n", + "* 获取你的OpenAI API Key\n", + "* 直接调用OpenAI的API\n", + "* 通过LangChain进行的API调用:\n", + " * 提示(Prompts)\n", + " * [模型(Models)](#model)\n", + " * 输出解析器(Output parsers)\n", + " " ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ - "## 2.1 获取你的OpenAI API Key\n", + "## 获取你的OpenAI API Key\n", "\n", "登陆[OpenAI账户获取你的API Key](https://platform.openai.com/account/api-keys) " ] @@ -59,12 +39,22 @@ "# 下载需要的包python-dotenv和openai\n", "# 如果你需要查看安装过程日志,可删除 -q \n", "!pip install -q python-dotenv\n", - "!pip install -q openai" + "!pip install -q openai\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# 将自己的 API-KEY 导入系统环境变量(关于如何设置参考这篇文章:https://zhuanlan.zhihu.com/p/627665725)\n", + "!export OPENAI_API_KEY='api-key' #api_key替换为自己的" + ] + }, + { + "cell_type": "code", + "execution_count": 1, "metadata": { "tags": [] }, @@ -72,26 +62,29 @@ "source": [ "import os\n", "import openai\n", - "# 运行此API配置,需要将目录中的.env中api_key替换为自己的\n", "from dotenv import load_dotenv, find_dotenv\n", - "_ = load_dotenv(find_dotenv()) # read local .env file\n", - "# 导入 OpenAI API_KEY\n", - "openai.api_key = os.environ['OPENAI_API_KEY']" + "\n", + "# 读取本地的环境变量 \n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ['OPENAI_API_KEY'] " ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ - "## 2.2 使用Chat API:OpenAI\n", + "## Chat API:OpenAI\n", "\n", "我们先从直接调用OpenAI的API开始。\n", "\n", "`get_completion`函数是基于`openai`的封装函数,对于给定提示(prompt)输出相应的回答。其包含两个参数\n", " \n", - " - `prompt` 必需输入参数。 你给模型的提示,可以是一个问题,可以是你需要模型帮助你做的事(改变文本写作风格,翻译,回复消息等等)。\n", + " - `prompt` 必需输入参数。 你给模型的**提示,可以是一个问题,可以是你需要模型帮助你做的事**(改变文本写作风格,翻译,回复消息等等)。\n", " - `model` 非必需输入参数。默认使用gpt-3.5-turbo。你也可以选择其他模型。\n", " \n", "这里的提示对应我们给chatgpt的问题,函数给出的输出则对应chatpgt给我们的答案。" @@ -99,7 +92,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": { "tags": [] }, @@ -118,12 +111,13 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ - "### 2.2.1 一个简单的例子\n", + "### 一个简单的例子\n", "\n", "我们来一个简单的例子 - 分别用中英文问问模型\n", "\n", @@ -133,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -142,12 +136,12 @@ "'1+1等于2。'" ] }, - "execution_count": 5, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ + "# 中文\n", "get_completion(\"1+1是什么?\")" ] }, @@ -170,14 +164,16 @@ } ], "source": [ + "# 英文\n", "get_completion(\"What is 1+1?\")" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.2.2 复杂一点的例子\n", + "### 复杂一点例子\n", "\n", "上面的简单例子,模型`gpt-3.5-turbo`对我们的关于1+1是什么的提问给出了回答。\n", "\n", @@ -205,6 +201,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -231,6 +228,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -270,6 +268,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -278,10 +277,8 @@ }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "tags": [] - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "response = get_completion(prompt)" @@ -310,6 +307,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -323,25 +321,164 @@ ] }, { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 中文" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "假设我们是电商公司员工,我们的顾客是一名海盗A,他在我们的网站上买了一个榨汁机用来做奶昔,在制作奶昔的过程中,奶昔的盖子飞了出去,弄得厨房墙上到处都是。于是海盗A给我们的客服中心写来以下邮件:`customer_email`" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# 非正式用语\n", + "customer_email = \"\"\" \n", + "阿,我很生气,\\\n", + "因为我的搅拌机盖掉了,\\\n", + "把奶昔溅到了厨房的墙上!\\\n", + "更糟糕的是,保修不包括打扫厨房的费用。\\\n", + "我现在需要你的帮助,伙计!\n", + "\"\"\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们的客服人员对于海盗的措辞表达觉得有点难以理解。 现在我们想要实现两个小目标:\n", + "\n", + "- 让模型用比较正式的普通话的表达方式将海盗的邮件进行翻译,客服人员可以更好理解。\n", + "- 让模型在翻译是用平和尊重的语气进行表达,客服人员的心情也会更好。\n", + "\n", + "根据这两个小目标,定义一下文本表达风格:`style`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# 普通话 + 平静、尊敬的语调\n", + "style = \"\"\"正式普通话 \\\n", + "用一个平静、尊敬的语调\n", + "\"\"\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "下一步需要做的是将`customer_email`和`style`结合起来构造我们的提示:`prompt`" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "把由三个反引号分隔的文本text翻译成一种正式普通话 用一个平静、尊敬的语调\n", + "风格。\n", + "text: ``` \n", + "阿,我很生气,因为我的搅拌机盖掉了,把奶昔溅到了厨房的墙上!更糟糕的是,保修不包括打扫厨房的费用。我现在需要你的帮助,伙计!\n", + "```\n", + "\n" + ] + } + ], + "source": [ + "# 要求模型根据给出的语调进行转化\n", + "prompt = f\"\"\"把由三个反引号分隔的文本text\\\n", + "翻译成一种{style}风格。\n", + "text: ```{customer_email}```\n", + "\"\"\"\n", + "\n", + "print(prompt)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`prompt` 构造好了,我们可以调用`get_completion`得到我们想要的结果 - 用平和尊重的普通话语气去表达一封带着方言表达方式的邮件" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "response = get_completion(prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'尊敬的朋友,我感到不安,因为我的搅拌机盖子不慎掉落,导致奶昔溅到了厨房的墙壁上!更加令人糟心的是,保修并不包含厨房清洁的费用。此刻,我需要你的帮助,亲爱的朋友!'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ - "## 2.3 使用Chat API:LangChain\n", + "## Chat API:LangChain\n", "\n", - "在前面一部分,我们通过封装函数`get_completion`直接调用了OpenAI完成了对海岛邮件进行了翻译,得到用平和尊重的语气、美式英语表达的邮件。\n", + "在前面一部分,我们通过封装函数`get_completion`直接调用了OpenAI完成了对方言邮件进行了的翻译,得到用平和尊重的语气、正式的普通话表达的邮件。\n", "\n", "让我们尝试使用LangChain来实现相同的功能。" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "^C\n" + ] + } + ], "source": [ "# 如果你需要查看安装过程日志,可删除 -q \n", "# --upgrade 让我们可以安装到最新版本的 langchain\n", @@ -349,19 +486,20 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ - "### 2.3.1 模型\n", + "### 模型\n", "\n", "从`langchain.chat_models`导入`OpenAI`的对话模型`ChatOpenAI`。 除去OpenAI以外,`langchain.chat_models`还集成了其他对话模型,更多细节可以查看[Langchain官方文档](https://python.langchain.com/en/latest/modules/models/chat/integrations.html)。" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": { "tags": [] }, @@ -372,7 +510,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "metadata": { "tags": [] }, @@ -380,10 +518,10 @@ { "data": { "text/plain": [ - "ChatOpenAI(verbose=False, callbacks=None, callback_manager=None, client=, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key=None, openai_api_base=None, openai_organization=None, openai_proxy=None, request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None)" + "ChatOpenAI(verbose=False, callbacks=None, callback_manager=None, client=, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key=None, openai_api_base=None, openai_organization=None, request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None)" ] }, - "execution_count": 7, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -396,6 +534,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -403,10 +542,11 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.3.2 提示模板\n", + "### 提示模板\n", "\n", "在前面的例子中,我们通过[f字符串](https://docs.python.org/zh-cn/3/tutorial/inputoutput.html#tut-f-strings)把Python表达式的值`style`和`customer_email`添加到`prompt`字符串内。\n", "\n", @@ -421,10 +561,11 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "#### 📚 使用LongChain提示模版\n", + "#### 📚 使用LangChain提示模版\n", "##### 1️⃣ 构造提示模版字符串\n", "我们构造一个提示模版字符串:`template_string`" ] @@ -445,6 +586,20 @@ ] }, { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "template_string = \"\"\"把由三个反引号分隔的文本text\\\n", + "翻译成一种{style}风格。\\\n", + "text: ```{text}```\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -454,7 +609,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 18, "metadata": { "tags": [] }, @@ -488,6 +643,28 @@ ] }, { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "PromptTemplate(input_variables=['style', 'text'], output_parser=None, partial_variables={}, template='把由三个反引号分隔的文本text翻译成一种{style}风格。text: ```{text}```\\n', template_format='f-string', validate_template=True)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 中文\n", + "prompt_template.messages[0].prompt" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -517,6 +694,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -540,6 +718,18 @@ "\"\"\"" ] }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "customer_style = \"\"\"正式普通话 \\\n", + "用一个平静、尊敬的语气\n", + "\"\"\"" + ] + }, { "cell_type": "code", "execution_count": 12, @@ -559,6 +749,23 @@ ] }, { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "customer_email = \"\"\"\n", + "阿,我很生气,\\\n", + "因为我的搅拌机盖掉了,\\\n", + "把奶昔溅到了厨房的墙上!\\\n", + "更糟糕的是,保修不包括打扫厨房的费用。\\\n", + "我现在需要你的帮助,伙计!\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -567,7 +774,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 22, "metadata": { "tags": [] }, @@ -600,6 +807,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -628,6 +836,25 @@ ] }, { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "content='把由三个反引号分隔的文本text翻译成一种正式普通话 用一个平静、尊敬的语气\\n风格。text: ```\\n阿,我很生气,因为我的搅拌机盖掉了,把奶昔溅到了厨房的墙上!更糟糕的是,保修不包括打扫厨房的费用。我现在需要你的帮助,伙计!\\n```\\n' additional_kwargs={} example=False\n" + ] + } + ], + "source": [ + "# 中文\n", + "print(customer_messages[0])" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -638,7 +865,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 25, "metadata": { "tags": [] }, @@ -667,6 +894,24 @@ ] }, { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "尊敬的伙计,我感到非常不安,因为我的搅拌机盖子不慎掉落,导致奶昔溅到了厨房的墙壁上!更加令人糟心的是,保修并不包括厨房清洁的费用。现在,我非常需要您的帮助!\n" + ] + } + ], + "source": [ + "print(customer_response.content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -698,10 +943,24 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [] - }, + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "service_reply = \"\"\"嘿,顾客, \\\n", + "保修不包括厨房的清洁费用, \\\n", + "因为您在启动搅拌机之前 \\\n", + "忘记盖上盖子而误用搅拌机, \\\n", + "这是您的错。 \\\n", + "倒霉! 再见!\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "service_style_pirate = \"\"\"\\\n", @@ -710,6 +969,21 @@ "\"\"\"" ] }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# 中文\n", + "service_style_pirate = \"\"\"\\\n", + "一个有礼貌的语气 \\\n", + "使用正式的普通话\\\n", + "\"\"\"" + ] + }, { "cell_type": "code", "execution_count": 18, @@ -736,6 +1010,30 @@ ] }, { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "把由三个反引号分隔的文本text翻译成一种一个有礼貌的语气 使用正式的普通话风格。text: ```嘿,顾客, 保修不包括厨房的清洁费用, 因为您在启动搅拌机之前 忘记盖上盖子而误用搅拌机, 这是您的错。 倒霉! 再见!\n", + "```\n", + "\n" + ] + } + ], + "source": [ + "service_messages = prompt_template.format_messages(\n", + " style=service_style_pirate,\n", + " text=service_reply)\n", + "\n", + "print(service_messages[0].content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -765,6 +1063,25 @@ ] }, { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "尊敬的顾客,根据保修条款,厨房清洁费用不在保修范围内。这是因为在使用搅拌机之前,您忘记盖上盖子而导致误用搅拌机,这属于您的疏忽。非常抱歉给您带来困扰!祝您好运!再见!\n" + ] + } + ], + "source": [ + "service_response = chat(service_messages)\n", + "print(service_response.content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] @@ -776,11 +1093,12 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "\n", - "在应用于比较复杂的场景时,提示可能会非常长并且包含涉及许多细节。使用提示模版,可以让我们更为方便地重复使用设计好的提示。\n", + "在应用于比较复杂的场景时,提示可能会非常长并且包含涉及许多细节。**使用提示模版,可以让我们更为方便地重复使用设计好的提示**。\n", "\n", "下面给出了一个比较长的提示模版案例。学生们线上学习并提交作业,通过以下的提示来实现对学生的提交的作业的评分。\n", "\n", @@ -829,6 +1147,56 @@ " \"\"\"\n", "```\n", "\n", + "# 中文\n", + "\n", + "```python\n", + " prompt = \"\"\" 你的任务是判断学生的解决方案是正确的还是不正确的\n", + "\n", + " 要解决该问题,请执行以下操作:\n", + " - 首先,制定自己的问题解决方案\n", + " - 然后将您的解决方案与学生的解决方案进行比较\n", + " 并评估学生的解决方案是否正确。\n", + " ...\n", + " 使用下面的格式:\n", + "\n", + " 问题:\n", + " ```\n", + " 问题文本\n", + " ```\n", + " 学生的解决方案:\n", + " ```\n", + " 学生的解决方案文本\n", + " ```\n", + " 实际解决方案:\n", + " ```\n", + " ...\n", + " 制定解决方案的步骤以及您的解决方案请参见此处\n", + " ```\n", + " 学生的解决方案和实际解决方案是否相同 \\\n", + " 只计算:\n", + " ```\n", + " 是或者不是\n", + " ```\n", + " 学生的成绩\n", + " ```\n", + " 正确或者不正确\n", + " ```\n", + " \n", + " 问题:\n", + " ```\n", + " {question}\n", + " ```\n", + " 学生的解决方案:\n", + " ```\n", + " {student's solution}\n", + " ```\n", + " 实际解决方案:\n", + " \n", + " \"\"\"\n", + "```\n", + "\n", + "\n", + "\n", "此外,LangChain还提供了提示模版用于一些常用场景。比如summarization, Question answering, or connect to sql databases, or connect to different APIs. 通过使用LongChain内置的提示模版,你可以快速建立自己的大模型应用,而不需要花时间去设计和构造提示。\n", "\n", "最后,我们在建立大模型应用时,通常希望模型的输出为给定的格式,比如在输出使用特定的关键词来让输出结构化。 下面为一个使用大模型进行链式思考推理例子,对于问题:`What is the elevation range for the area that the eastern sector of the Colorado orogeny extends into?`, 通过使用LangChain库函数,输出采用\"Thought\"(思考)、\"Action\"(行动)、\"Observation\"(观察)作为链式思考推理的关键词,让输出结构化。在[补充材料](#reason_act)中,可以查看使用LangChain和OpenAI进行链式思考推理的另一个代码实例。\n", @@ -855,17 +1223,44 @@ "Action: Finish[1,800 to 7,000 ft]\n", "\n", "\"\"\"\n", + "```\n", + "\n", + "\n", + "```python\n", + "\"\"\"\n", + "想法:我需要搜索科罗拉多造山带,找到科罗拉多造山带东段延伸到的区域,然后找到该区域的高程范围。\n", + "行动:搜索[科罗拉多造山运动]\n", + "观察:科罗拉多造山运动是科罗拉多州及周边地区造山运动(造山运动)的一次事件。\n", + "\n", + "想法:它没有提到东区。 所以我需要查找东区。\n", + "行动:查找[东区]\n", + "观察:(结果1 / 1)东段延伸至高原,称为中原造山运动。\n", + "\n", + "想法:科罗拉多造山运动的东段延伸至高原。 所以我需要搜索高原并找到它的海拔范围。\n", + "行动:搜索[高地平原]\n", + "观察:高原是指两个不同的陆地区域之一\n", + "\n", + "想法:我需要搜索高地平原(美国)。\n", + "行动:搜索[高地平原(美国)]\n", + "观察:高地平原是大平原的一个分区。 从东到西,高原的海拔从 1,800 英尺左右上升到 7,000 英尺(550 到 2,130 米)。[3]\n", + "\n", + "想法:高原的海拔从大约 1,800 英尺上升到 7,000 英尺,所以答案是 1,800 到 7,000 英尺。\n", + "动作:完成[1,800 至 7,000 英尺]\n", + "\n", + "\"\"\"\n", "```\n" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.3.3 输出解析器" + "### 输出解析器" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -902,6 +1297,27 @@ ] }, { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "customer_review = \"\"\"\\\n", + "这款吹叶机非常神奇。 它有四个设置:\\\n", + "吹蜡烛、微风、风城、龙卷风。 \\\n", + "两天后就到了,正好赶上我妻子的\\\n", + "周年纪念礼物。 \\\n", + "我想我的妻子会喜欢它到说不出话来。 \\\n", + "到目前为止,我是唯一一个使用它的人,而且我一直\\\n", + "每隔一天早上用它来清理草坪上的叶子。 \\\n", + "它比其他吹叶机稍微贵一点,\\\n", + "但我认为它的额外功能是值得的。\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -936,6 +1352,35 @@ ] }, { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "review_template = \"\"\"\\\n", + "对于以下文本,请从中提取以下信息:\n", + "\n", + "礼物:该商品是作为礼物送给别人的吗? \\\n", + "如果是,则回答 是的;如果否或未知,则回答 不是。\n", + "\n", + "交货天数:产品需要多少天\\\n", + "到达? 如果没有找到该信息,则输出-1。\n", + "\n", + "价钱:提取有关价值或价格的任何句子,\\\n", + "并将它们输出为逗号分隔的 Python 列表。\n", + "\n", + "使用以下键将输出格式化为 JSON:\n", + "礼物\n", + "交货天数\n", + "价钱\n", + "\n", + "文本: {text}\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -962,6 +1407,26 @@ ] }, { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "input_variables=['text'] output_parser=None partial_variables={} messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['text'], output_parser=None, partial_variables={}, template='对于以下文本,请从中提取以下信息:\\n\\n礼物:该商品是作为礼物送给别人的吗? 如果是,则回答 是的;如果否或未知,则回答 不是。\\n\\n交货天数:产品需要多少天到达? 如果没有找到该信息,则输出-1。\\n\\n价钱:提取有关价值或价格的任何句子,并将它们输出为逗号分隔的 Python 列表。\\n\\n使用以下键将输出格式化为 JSON:\\n礼物\\n交货天数\\n价钱\\n\\n文本: {text}\\n', template_format='f-string', validate_template=True), additional_kwargs={})]\n" + ] + } + ], + "source": [ + "from langchain.prompts import ChatPromptTemplate\n", + "prompt_template = ChatPromptTemplate.from_template(review_template)\n", + "print(prompt_template)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -970,7 +1435,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -978,6 +1443,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1008,6 +1474,30 @@ ] }, { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"礼物\": \"是的\",\n", + " \"交货天数\": 2,\n", + " \"价钱\": [\"它比其他吹叶机稍微贵一点\"]\n", + "}\n" + ] + } + ], + "source": [ + "chat = ChatOpenAI(temperature=0.0)\n", + "response = chat(messages)\n", + "print(response.content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1057,6 +1547,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1064,6 +1555,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1095,6 +1587,30 @@ ] }, { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "review_template_2 = \"\"\"\\\n", + "对于以下文本,请从中提取以下信息::\n", + "\n", + "礼物:该商品是作为礼物送给别人的吗?\n", + "如果是,则回答 是的;如果否或未知,则回答 不是。\n", + "\n", + "交货天数:产品到达需要多少天? 如果没有找到该信息,则输出-1。\n", + "\n", + "价钱:提取有关价值或价格的任何句子,并将它们输出为逗号分隔的 Python 列表。\n", + "\n", + "文本: {text}\n", + "\n", + "{format_instructions}\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1103,7 +1619,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -1111,6 +1627,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1161,6 +1678,56 @@ " price, and output them as a \\\n", " comma separated Python list.\")\n", "\n", + "\n", + "response_schemas = [gift_schema, \n", + " delivery_days_schema,\n", + " price_value_schema]\n", + "output_parser = StructuredOutputParser.from_response_schemas(response_schemas)\n", + "format_instructions = output_parser.get_format_instructions()\n", + "print(format_instructions)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The output should be a markdown code snippet formatted in the following schema, including the leading and trailing \"\\`\\`\\`json\" and \"\\`\\`\\`\":\n", + "\n", + "```json\n", + "{\n", + "\t\"礼物\": string // 这件物品是作为礼物送给别人的吗? 如果是,则回答 是的, 如果否或未知,则回答 不是。\n", + "\t\"交货天数\": string // 产品需要多少天才能到达? 如果没有找到该信息,则输出-1。\n", + "\t\"价钱\": string // 提取有关价值或价格的任何句子, 并将它们输出为逗号分隔的 Python 列表\n", + "}\n", + "```\n" + ] + } + ], + "source": [ + "# 中文\n", + "from langchain.output_parsers import ResponseSchema\n", + "from langchain.output_parsers import StructuredOutputParser\n", + "\n", + "gift_schema = ResponseSchema(name=\"礼物\",\n", + " description=\"这件物品是作为礼物送给别人的吗?\\\n", + " 如果是,则回答 是的,\\\n", + " 如果否或未知,则回答 不是。\")\n", + "\n", + "delivery_days_schema = ResponseSchema(name=\"交货天数\",\n", + " description=\"产品需要多少天才能到达?\\\n", + " 如果没有找到该信息,则输出-1。\")\n", + "\n", + "price_value_schema = ResponseSchema(name=\"价钱\",\n", + " description=\"提取有关价值或价格的任何句子,\\\n", + " 并将它们输出为逗号分隔的 Python 列表\")\n", + "\n", + "\n", "response_schemas = [gift_schema, \n", " delivery_days_schema,\n", " price_value_schema]\n", @@ -1170,6 +1737,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1178,7 +1746,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -1223,6 +1791,46 @@ ] }, { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "对于以下文本,请从中提取以下信息::\n", + "\n", + "礼物:该商品是作为礼物送给别人的吗?\n", + "如果是,则回答 是的;如果否或未知,则回答 不是。\n", + "\n", + "交货天数:产品到达需要多少天? 如果没有找到该信息,则输出-1。\n", + "\n", + "价钱:提取有关价值或价格的任何句子,并将它们输出为逗号分隔的 Python 列表。\n", + "\n", + "文本: 这款吹叶机非常神奇。 它有四个设置:吹蜡烛、微风、风城、龙卷风。 两天后就到了,正好赶上我妻子的周年纪念礼物。 我想我的妻子会喜欢它到说不出话来。 到目前为止,我是唯一一个使用它的人,而且我一直每隔一天早上用它来清理草坪上的叶子。 它比其他吹叶机稍微贵一点,但我认为它的额外功能是值得的。\n", + "\n", + "\n", + "The output should be a markdown code snippet formatted in the following schema, including the leading and trailing \"\\`\\`\\`json\" and \"\\`\\`\\`\":\n", + "\n", + "```json\n", + "{\n", + "\t\"礼物\": string // 这件物品是作为礼物送给别人的吗? 如果是,则回答 是的, 如果否或未知,则回答 不是。\n", + "\t\"交货天数\": string // 产品需要多少天才能到达? 如果没有找到该信息,则输出-1。\n", + "\t\"价钱\": string // 提取有关价值或价格的任何句子, 并将它们输出为逗号分隔的 Python 列表\n", + "}\n", + "```\n", + "\n" + ] + } + ], + "source": [ + "# 中文\n", + "print(messages[0].content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1254,6 +1862,32 @@ ] }, { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "```json\n", + "{\n", + "\t\"礼物\": \"不是\",\n", + "\t\"交货天数\": \"两天后就到了\",\n", + "\t\"价钱\": \"它比其他吹叶机稍微贵一点\"\n", + "}\n", + "```\n" + ] + } + ], + "source": [ + "# 中文\n", + "response = chat(messages)\n", + "print(response.content)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1284,6 +1918,28 @@ ] }, { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'礼物': '不是', '交货天数': '两天后就到了', '价钱': '它比其他吹叶机稍微贵一点'}" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_dict = output_parser.parse(response.content)\n", + "output_dict" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1332,13 +1988,15 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## 2.4 补充材料" + "## 补充材料" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -1357,9 +2015,99 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 56, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mThought: I need to search David Chanoff and find the U.S. Navy admiral he collaborated with. Then I need to find the president under whom the admiral served as the ambassador to the United Kingdom.\n", + "Action: Search[David Chanoff]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mDavid Chanoff is a noted author of non-fiction work. His work has typically involved collaborations with the principal protagonist of the work concerned. His collaborators have included; Augustus A. White, Joycelyn Elders, Đoàn Văn Toại, William J. Crowe, Ariel Sharon, Kenneth Good and Felix Zandman. He has also written about a wide range of subjects including literary history, education and foreign for The Washington Post, The New Republic and The New York Times Magazine. He has published more than twelve books.\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mDavid Chanoff has collaborated with several individuals, including Augustus A. White, Joycelyn Elders, Đoàn Văn Toại, William J. Crowe, Ariel Sharon, Kenneth Good, and Felix Zandman. I need to search each of these individuals to find the U.S. Navy admiral. \n", + "Action: Search[Augustus A. White]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mAugustus A. White III (born June 4, 1936) is the Ellen and Melvin Gordon Distinguished Professor of Medical Education and Professor of Orthopedic Surgery at Harvard Medical School and a former Orthopaedic Surgeon-in-Chief at Beth Israel Hospital, Boston, Massachusetts. White was the first African American medical student at Stanford, surgical resident at Yale University, professor of medicine at Yale, and department head at a Harvard-affiliated hospital (Beth Israel Hospital).\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mAugustus A. White III is not a U.S. Navy admiral. I need to search the next individual, Joycelyn Elders.\n", + "Action: Search[Joycelyn Elders]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mMinnie Joycelyn Elders (born Minnie Lee Jones; August 13, 1933) is an American pediatrician and public health administrator who served as Surgeon General of the United States from 1993 to 1994. A vice admiral in the Public Health Service Commissioned Corps, she was the second woman, second person of color, and first African American to serve as Surgeon General. \n", + "Elders is best known for her frank discussion of her views on controversial issues such as drug legalization, masturbation, and distributing contraception in schools. She was forced to resign in December 1994 amidst controversy as a result of her views. She is currently a professor emerita of pediatrics at the University of Arkansas for Medical Sciences.\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mJoycelyn Elders is a pediatrician and public health administrator, not a U.S. Navy admiral. I need to search the next individual, Đoàn Văn Toại.\n", + "Action: Search[Đoàn Văn Toại]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mĐoàn Văn Toại (1945 in Vietnam – November 2017 in California) was a Vietnamese-born naturalized American activist and the author of The Vietnamese Gulag (Simon & Schuster, 1986).\u001b[0m\n", + "Thought:" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32;1m\u001b[1;3mĐoàn Văn Toại is an activist and author, not a U.S. Navy admiral. I need to search the next individual, William J. Crowe.\n", + "Action: Search[William J. Crowe]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mWilliam James Crowe Jr. (January 2, 1925 – October 18, 2007) was a United States Navy admiral and diplomat who served as the 11th chairman of the Joint Chiefs of Staff under Presidents Ronald Reagan and George H. W. Bush, and as the ambassador to the United Kingdom and Chair of the Intelligence Oversight Board under President Bill Clinton.\u001b[0m\n", + "Thought:" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32;1m\u001b[1;3mWilliam J. Crowe is a U.S. Navy admiral and diplomat. I need to find the president under whom he served as the ambassador to the United Kingdom.\n", + "Action: Search[William J. Crowe ambassador to United Kingdom]\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mWilliam James Crowe Jr. (January 2, 1925 – October 18, 2007) was a United States Navy admiral and diplomat who served as the 11th chairman of the Joint Chiefs of Staff under Presidents Ronald Reagan and George H. W. Bush, and as the ambassador to the United Kingdom and Chair of the Intelligence Oversight Board under President Bill Clinton.\u001b[0m\n", + "Thought:" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.llms.openai.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32;1m\u001b[1;3mWilliam J. Crowe served as the ambassador to the United Kingdom under President Bill Clinton. So the answer is Bill Clinton.\n", + "Action: Finish[Bill Clinton]\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'Bill Clinton'" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from langchain.docstore.wikipedia import Wikipedia\n", "from langchain.llms import OpenAI\n", @@ -1398,6 +2146,13 @@ "question = \"Author David Chanoff has collaborated with a U.S. Navy admiral who served as the ambassador to the United Kingdom under which President?\"\n", "agent_executor.run(question)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -1416,30 +2171,8 @@ "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": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": { - "height": "calc(100% - 180px)", - "left": "10px", - "top": "150px", - "width": "165px" - }, - "toc_section_display": true, - "toc_window_display": true - }, - "toc-autonumbering": false, - "toc-showcode": false, - "toc-showmarkdowntxt": false, - "toc-showtags": false + "version": "3.10.9" + } }, "nbformat": 4, "nbformat_minor": 4 diff --git a/content/LangChain for LLM Application Development/4.模型链.ipynb b/content/LangChain for LLM Application Development/4.模型链.ipynb index 396fe07..7477286 100644 --- a/content/LangChain for LLM Application Development/4.模型链.ipynb +++ b/content/LangChain for LLM Application Development/4.模型链.ipynb @@ -1,34 +1,35 @@ { "cells": [ { - "cell_type": "markdown", - "id": "7ee04154", - "metadata": { - "toc": true - }, - "source": [ - "
  • 4. 模型链
  • " - ] - }, - { + "attachments": {}, "cell_type": "markdown", "id": "52824b89-532a-4e54-87e9-1410813cd39e", "metadata": {}, "source": [ - "# 4. 模型链" + "# Chains in LangChain(LangChain中的链)\n", + "\n", + "## Outline\n", + "\n", + "* LLMChain(大语言模型链)\n", + "* Sequential Chains(顺序链)\n", + " * SimpleSequentialChain\n", + " * SequentialChain\n", + "* Router Chain(路由链)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "54810ef7", "metadata": {}, "source": [ - "模型链允许我们将多个组件组合在一起,以创建一个单一的、连贯的应用程序。链(Chains)通常将一个LLM(大语言模型)与提示结合在一起,使用这个构建块,您还可以将一堆这些构建块组合在一起,对您的文本或其他数据进行一系列操作。例如,我们可以创建一个链,该链接受用户输入,使用提示模板对其进行格式化,然后将格式化的响应传递给LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合在一起来构建更复杂的链。" + "### 为什么我们需要Chains ?\n", + "链允许我们将多个组件组合在一起,以创建一个单一的、连贯的应用程序。链(Chains)通常将一个LLM(大语言模型)与提示结合在一起,使用这个构建块,您还可以将一堆这些构建块组合在一起,对您的文本或其他数据进行一系列操作。例如,我们可以创建一个链,该链接受用户输入,使用提示模板对其进行格式化,然后将格式化的响应传递给LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合在一起来构建更复杂的链。" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 44, "id": "541eb2f1", "metadata": {}, "outputs": [], @@ -39,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 45, "id": "b7ed03ed-1322-49e3-b2a2-33e94fb592ef", "metadata": { "tags": [] @@ -47,14 +48,18 @@ "outputs": [], "source": [ "import os\n", - "\n", + "import openai\n", "from dotenv import load_dotenv, find_dotenv\n", - "_ = load_dotenv(find_dotenv()) # 读取本地 .env 文件" + "\n", + "_ = load_dotenv(find_dotenv()) # 读取本地 .env 文件\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ['OPENAI_API_KEY'] #\"填入你的专属的API key\"" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "b84e441b", "metadata": {}, "outputs": [], @@ -63,6 +68,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "663fc885", "metadata": {}, @@ -72,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 46, "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", "metadata": {}, "outputs": [], @@ -83,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 47, "id": "b7a09c35", "metadata": {}, "outputs": [ @@ -151,7 +157,7 @@ "4 Milk Frother Handheld\\n  I loved this product. But they only seem to l..." ] }, - "execution_count": 11, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -161,24 +167,26 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "b940ce7c", "metadata": {}, "source": [ - "## 4.1 大语言模型链" + "## 1. LLMChain" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "e000bd16", "metadata": {}, "source": [ - "大语言模型链(LLMChain)是一个简单但非常强大的链,也是后面我们将要介绍的许多链的基础。" + "LLMChain是一个简单但非常强大的链,也是后面我们将要介绍的许多链的基础。" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 48, "id": "e92dff22", "metadata": {}, "outputs": [], @@ -189,6 +197,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "94a32c6f", "metadata": {}, @@ -198,16 +207,16 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "id": "943237a7", "metadata": {}, "outputs": [], "source": [ - "OPENAI_API_KEY = \"********\" #\"填入你的专属的API key\"\n", - "llm = ChatOpenAI(temperature=0.0,openai_api_key=OPENAI_API_KEY) #预测下一个token时,概率越大的值就越平滑(平滑也就是让差异大的值之间的差异变得没那么大),temperature值越小则生成的内容越稳定" + "llm = ChatOpenAI(temperature=0.0) #预测下一个token时,概率越大的值就越平滑(平滑也就是让差异大的值之间的差异变得没那么大),temperature值越小则生成的内容越稳定" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "81887434", "metadata": {}, @@ -229,6 +238,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "5c22cb13", "metadata": {}, @@ -247,6 +257,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "8d7d5ff6", "metadata": {}, @@ -277,6 +288,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "1e1ede1c", "metadata": {}, @@ -286,17 +298,17 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "id": "2181be10", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'蓝耳科技 (BlueEar Technologies)'" + "'\"豪华床纺\"'" ] }, - "execution_count": 12, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -304,34 +316,36 @@ "source": [ "# 中文\n", "prompt = ChatPromptTemplate.from_template( \n", - " \"描述制造{product}的公司的最佳名称是什么?\"\n", + " \"描述制造{product}的一个公司的最佳名称是什么?\"\n", ")\n", "chain = LLMChain(llm=llm, prompt=prompt)\n", - "product = \"蓝牙耳机\"\n", + "product = \"大号床单套装\"\n", "chain.run(product)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "49158430", "metadata": {}, "source": [ - "## 4.2 顺序链" + "## 2. Sequential Chains" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "69b03469", "metadata": {}, "source": [ - "### 4.2.1 简单顺序链\n", + "### 2.1 SimpleSequentialChain\n", "\n", "顺序链(Sequential Chains)是按预定义顺序执行其链接的链。具体来说,我们将使用简单顺序链(SimpleSequentialChain),这是顺序链的最简单类型,其中每个步骤都有一个输入/输出,一个步骤的输出是下一个步骤的输入" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "id": "febee243", "metadata": {}, "outputs": [], @@ -341,16 +355,16 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "id": "5d019d6f", "metadata": {}, "outputs": [], "source": [ - "OPENAI_API_KEY = \"********\" #\"填入你的专属的API key\"\n", - "llm = ChatOpenAI(temperature=0.9,openai_api_key=OPENAI_API_KEY)" + "llm = ChatOpenAI(temperature=0.9)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "0e732589", "metadata": {}, @@ -377,6 +391,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "dcfca7bd", "metadata": {}, @@ -402,6 +417,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "3a1991f4", "metadata": {}, @@ -422,6 +438,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "5122f26a", "metadata": {}, @@ -466,7 +483,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 19, "id": "c7c32997", "metadata": {}, "outputs": [ @@ -477,8 +494,8 @@ "\n", "\n", "\u001b[1m> Entering new SimpleSequentialChain chain...\u001b[0m\n", - "\u001b[36;1m\u001b[1;3m“蓝牙耳机制造公司”或“蓝耳制造公司”均可。具体名称应根据公司的定位、目标市场、品牌理念等因素来考虑。\u001b[0m\n", - "\u001b[33;1m\u001b[1;3m专业生产蓝牙耳机的公司,致力于提供高品质、时尚设计、舒适佩戴的产品,满足用户多样化的需求。\u001b[0m\n", + "\u001b[36;1m\u001b[1;3m\"尺寸王床品有限公司\"\u001b[0m\n", + "\u001b[33;1m\u001b[1;3m尺寸王床品有限公司是一家专注于床上用品生产的公司。\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] @@ -486,18 +503,19 @@ { "data": { "text/plain": [ - "'专业生产蓝牙耳机的公司,致力于提供高品质、时尚设计、舒适佩戴的产品,满足用户多样化的需求。'" + "'尺寸王床品有限公司是一家专注于床上用品生产的公司。'" ] }, - "execution_count": 23, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 中文\n", + "\n", "first_prompt = ChatPromptTemplate.from_template( \n", - " \"描述制造{product}的公司的最佳名称是什么?\"\n", + " \"描述制造{product}的一个公司的最好的名称是什么\"\n", ")\n", "chain_one = LLMChain(llm=llm, prompt=first_prompt)\n", "\n", @@ -507,22 +525,25 @@ ")\n", "chain_two = LLMChain(llm=llm, prompt=second_prompt)\n", "\n", + "\n", "overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],\n", " verbose=True\n", " )\n", - "product = \"蓝牙耳机\"\n", + "product = \"大号床单套装\"\n", "overall_simple_chain.run(product)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "7b5ce18c", "metadata": {}, "source": [ - "### 4.2.2 顺序链" + "### 2.2 SequentialChain" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "1e69f4c0", "metadata": {}, @@ -534,7 +555,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "4c129ef6", "metadata": {}, "outputs": [], @@ -546,6 +567,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "3d4be4e8", "metadata": {}, @@ -555,16 +577,16 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "03a8e203", "metadata": {}, "outputs": [], "source": [ - "OPENAI_API_KEY = \"********\" #\"填入你的专属的API key\"\n", - "llm = ChatOpenAI(temperature=0.9,openai_api_key=OPENAI_API_KEY)" + "llm = ChatOpenAI(temperature=0.9)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "9811445c", "metadata": {}, @@ -574,7 +596,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 23, "id": "016187ac", "metadata": {}, "outputs": [], @@ -594,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 25, "id": "0fb0730e", "metadata": {}, "outputs": [], @@ -614,7 +636,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 26, "id": "6accf92d", "metadata": {}, "outputs": [], @@ -633,7 +655,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 27, "id": "c7a46121", "metadata": {}, "outputs": [], @@ -654,7 +676,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 28, "id": "89603117", "metadata": {}, "outputs": [], @@ -671,6 +693,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "0509de01", "metadata": {}, @@ -731,14 +754,131 @@ ] }, { + "cell_type": "code", + "execution_count": 9, + "id": "31624a7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new SequentialChain chain...\u001b[0m\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 1.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 2.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n", + "Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-kmMHlitaQynVMwTW3jDTCPga on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "{'Review': \"Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur...\\nVieux lot ou contrefaçon !?\",\n", + " 'English_Review': \"I find the taste mediocre. The foam doesn't last, it's strange. I buy the same ones in stores and the taste is much better...\\nOld batch or counterfeit?!\",\n", + " 'summary': \"The reviewer finds the taste mediocre and suspects that either the product is from an old batch or it might be counterfeit, as the foam doesn't last and the taste is not as good as the ones purchased in stores.\",\n", + " 'followup_message': \"后续回复: Bonjour! Je vous remercie de votre commentaire concernant notre produit. Nous sommes désolés d'apprendre que vous avez trouvé le goût moyen et que vous soupçonnez qu'il s'agit peut-être d'un ancien lot ou d'une contrefaçon, car la mousse ne dure pas et le goût n'est pas aussi bon que ceux achetés en magasin. Nous apprécions vos préoccupations et nous aimerions enquêter davantage sur cette situation. Pourriez-vous s'il vous plaît nous fournir plus de détails, tels que la date d'achat et le numéro de lot du produit? Nous sommes déterminés à offrir la meilleure qualité à nos clients et nous ferons tout notre possible pour résoudre ce problème. Merci encore pour votre commentaire et nous attendons votre réponse avec impatience. Cordialement.\"}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 中文\n", + "\n", + "#子链1\n", + "\n", + "# prompt模板 1: 翻译成英语(把下面的review翻译成英语)\n", + "first_prompt = ChatPromptTemplate.from_template(\n", + " \"把下面的评论review翻译成英文:\"\n", + " \"\\n\\n{Review}\"\n", + ")\n", + "# chain 1: 输入:Review 输出:英文的 Review\n", + "chain_one = LLMChain(llm=llm, prompt=first_prompt, \n", + " output_key=\"English_Review\"\n", + " )\n", + "\n", + "#子链2\n", + "\n", + "# prompt模板 2: 用一句话总结下面的 review\n", + "second_prompt = ChatPromptTemplate.from_template(\n", + " \"请你用一句话来总结下面的评论review:\"\n", + " \"\\n\\n{English_Review}\"\n", + ")\n", + "# chain 2: 输入:英文的Review 输出:总结\n", + "chain_two = LLMChain(llm=llm, prompt=second_prompt, \n", + " output_key=\"summary\"\n", + " )\n", + "\n", + "\n", + "#子链3\n", + "\n", + "# prompt模板 3: 下面review使用的什么语言\n", + "third_prompt = ChatPromptTemplate.from_template(\n", + " \"下面的评论review使用的什么语言:\\n\\n{Review}\"\n", + ")\n", + "# chain 3: 输入:Review 输出:语言\n", + "chain_three = LLMChain(llm=llm, prompt=third_prompt,\n", + " output_key=\"language\"\n", + " )\n", + "\n", + "\n", + "#子链4\n", + "\n", + "# prompt模板 4: 使用特定的语言对下面的总结写一个后续回复\n", + "fourth_prompt = ChatPromptTemplate.from_template(\n", + " \"使用特定的语言对下面的总结写一个后续回复:\"\n", + " \"\\n\\n总结: {summary}\\n\\n语言: {language}\"\n", + ")\n", + "# chain 4: 输入: 总结, 语言 输出: 后续回复\n", + "chain_four = LLMChain(llm=llm, prompt=fourth_prompt,\n", + " output_key=\"followup_message\"\n", + " )\n", + "\n", + "\n", + "# 对四个子链进行组合\n", + "\n", + "#输入:review 输出:英文review,总结,后续回复 \n", + "overall_chain = SequentialChain(\n", + " chains=[chain_one, chain_two, chain_three, chain_four],\n", + " input_variables=[\"Review\"],\n", + " output_variables=[\"English_Review\", \"summary\",\"followup_message\"],\n", + " verbose=True\n", + ")\n", + "\n", + "\n", + "review = df.Review[5]\n", + "overall_chain(review)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "3041ea4c", "metadata": {}, "source": [ - "## 4.3. 路由链" + "## 3. Router Chain(路由链)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "f0c32f97", "metadata": {}, @@ -747,7 +887,7 @@ "\n", "一个相当常见但基本的操作是根据输入将其路由到一条链,具体取决于该输入到底是什么。如果你有多个子链,每个子链都专门用于特定类型的输入,那么可以组成一个路由链,它首先决定将它传递给哪个子链,然后将它传递给那个链。\n", "\n", - "Router Chain(路由链)由两个组件组成:\n", + "路由器由两个组件组成:\n", "\n", "- 路由器链本身(负责选择要调用的下一个链)\n", "- destination_chains:路由器链可以路由到的链\n", @@ -756,16 +896,17 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "cb1b4708", "metadata": {}, "source": [ - "### 4.3.1 定义提示模板" + "### 定义提示模板" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 49, "id": "ade83f4f", "metadata": {}, "outputs": [], @@ -823,6 +964,60 @@ ] }, { + "cell_type": "code", + "execution_count": 51, + "id": "f7fade7a", + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "#第一个提示适合回答物理问题\n", + "physics_template = \"\"\"你是一个非常聪明的物理专家。 \\\n", + "你擅长用一种简洁并且易于理解的方式去回答问题。\\\n", + "当你不知道问题的答案时,你承认\\\n", + "你不知道.\n", + "\n", + "这是一个问题:\n", + "{input}\"\"\"\n", + "\n", + "\n", + "#第二个提示适合回答数学问题\n", + "math_template = \"\"\"你是一个非常优秀的数学家。 \\\n", + "你擅长回答数学问题。 \\\n", + "你之所以如此优秀, \\\n", + "是因为你能够将棘手的问题分解为组成部分,\\\n", + "回答组成部分,然后将它们组合在一起,回答更广泛的问题。\n", + "\n", + "这是一个问题:\n", + "{input}\"\"\"\n", + "\n", + "\n", + "#第三个适合回答历史问题\n", + "history_template = \"\"\"你是以为非常优秀的历史学家。 \\\n", + "你对一系列历史时期的人物、事件和背景有着极好的学识和理解\\\n", + "你有能力思考、反思、辩证、讨论和评估过去。\\\n", + "你尊重历史证据,并有能力利用它来支持你的解释和判断。\n", + "\n", + "这是一个问题:\n", + "{input}\"\"\"\n", + "\n", + "\n", + "#第四个适合回答计算机问题\n", + "computerscience_template = \"\"\" 你是一个成功的计算机科学专家。\\\n", + "你有创造力、协作精神、\\\n", + "前瞻性思维、自信、解决问题的能力、\\\n", + "对理论和算法的理解以及出色的沟通技巧。\\\n", + "你非常擅长回答编程问题。\\\n", + "你之所以如此优秀,是因为你知道 \\\n", + "如何通过以机器可以轻松解释的命令式步骤描述解决方案来解决问题,\\\n", + "并且你知道如何选择在时间复杂性和空间复杂性之间取得良好平衡的解决方案。\n", + "\n", + "这还是一个输入:\n", + "{input}\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "6922b35e", "metadata": {}, @@ -832,8 +1027,7 @@ }, { "cell_type": "code", - "execution_count": 32, - "id": "5f590e9f", + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -862,16 +1056,49 @@ ] }, { + "cell_type": "code", + "execution_count": 52, + "id": "deb8aafc", + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "prompt_infos = [\n", + " {\n", + " \"名字\": \"物理学\", \n", + " \"描述\": \"擅长回答关于物理学的问题\", \n", + " \"提示模板\": physics_template\n", + " },\n", + " {\n", + " \"名字\": \"数学\", \n", + " \"描述\": \"擅长回答数学问题\", \n", + " \"提示模板\": math_template\n", + " },\n", + " {\n", + " \"名字\": \"历史\", \n", + " \"描述\": \"擅长回答历史问题\", \n", + " \"提示模板\": history_template\n", + " },\n", + " {\n", + " \"名字\": \"计算机科学\", \n", + " \"描述\": \"擅长回答计算机科学问题\", \n", + " \"提示模板\": computerscience_template\n", + " }\n", + "]\n" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "80eb1de8", "metadata": {}, "source": [ - "### 4.3.2 导入相关的包" + "### 导入相关的包" ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 28, "id": "31b06fc8", "metadata": {}, "outputs": [], @@ -882,32 +1109,31 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "50c16f01", "metadata": {}, "source": [ - "### 4.3.3 定义语言模型" + "### 定义语言模型" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 29, "id": "f3f50bcc", "metadata": {}, "outputs": [], "source": [ - "OPENAI_API_KEY = \"********\" #\"填入你的专属的API key\"\n", - "llm = ChatOpenAI(temperature=0,openai_api_key=OPENAI_API_KEY)" + "llm = ChatOpenAI(temperature=0)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "8795cd42", "metadata": {}, "source": [ - "### 4.3.4 大语言模型路由链\n", - "\n", - "大语言模型路由链(LLMRouterChain)使用大语言模型(LLM)来确定如何路由事物\n", + "### LLMRouterChain(此链使用 LLM 来确定如何路由事物)\n", "\n", "在这里,我们需要一个**多提示链**。这是一种特定类型的链,用于在多个不同的提示模板之间进行路由。\n", "但是,这只是你可以路由的一种类型。你也可以在任何类型的链之间进行路由。\n", @@ -917,6 +1143,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "46633b43", "metadata": {}, @@ -927,12 +1154,11 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 30, "id": "8eefec24", "metadata": {}, "outputs": [], "source": [ - "\n", "destination_chains = {}\n", "for p_info in prompt_infos:\n", " name = p_info[\"name\"]\n", @@ -946,6 +1172,27 @@ ] }, { + "cell_type": "code", + "execution_count": null, + "id": "fd6eb641", + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "destination_chains = {}\n", + "for p_info in prompt_infos:\n", + " name = p_info[\"名字\"]\n", + " prompt_template = p_info[\"提示模板\"]\n", + " prompt = ChatPromptTemplate.from_template(template=prompt_template)\n", + " chain = LLMChain(llm=llm, prompt=prompt)\n", + " destination_chains[name] = chain \n", + " \n", + "destinations = [f\"{p['名字']}: {p['描述']}\" for p in prompt_infos]\n", + "destinations_str = \"\\n\".join(destinations)" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "eba115de", "metadata": {}, @@ -956,7 +1203,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 31, "id": "9f98018a", "metadata": {}, "outputs": [], @@ -966,6 +1213,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "948700c4", "metadata": {}, @@ -974,9 +1222,28 @@ "这包括要完成的任务的说明以及输出应该采用的特定格式。" ] }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "24f30c2c", + "metadata": {}, + "source": [ + "注意:此处在原教程的基础上添加了一个示例,主要是因为\"gpt-3.5-turbo\"模型不能很好适应理解模板的意思,使用 \"text-davinci-003\" 或者\"gpt-4-0613\"可以很好的工作,因此在这里多加了示例提示让其更好的学习。\n", + "eg:\n", + "<< INPUT >>\n", + "\"What is black body radiation?\"\n", + "<< OUTPUT >>\n", + "```json\n", + "{{{{\n", + " \"destination\": string \\ name of the prompt to use or \"DEFAULT\"\n", + " \"next_inputs\": string \\ a potentially modified version of the original input\n", + "}}}}\n", + "```" + ] + }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 32, "id": "11b2e2ba", "metadata": {}, "outputs": [], @@ -1009,10 +1276,79 @@ "<< INPUT >>\n", "{{input}}\n", "\n", - "<< OUTPUT (remember to include the ```json)>>\"\"\"" + "<< OUTPUT (remember to include the ```json)>>\n", + "\n", + "eg:\n", + "<< INPUT >>\n", + "\"What is black body radiation?\"\n", + "<< OUTPUT >>\n", + "```json\n", + "{{{{\n", + " \"destination\": string \\ name of the prompt to use or \"DEFAULT\"\n", + " \"next_inputs\": string \\ a potentially modified version of the original input\n", + "}}}}\n", + "```\n", + "\n", + "\"\"\"" ] }, { + "cell_type": "code", + "execution_count": null, + "id": "a7aae035", + "metadata": {}, + "outputs": [], + "source": [ + "# 中文\n", + "\n", + "# 多提示路由模板\n", + "MULTI_PROMPT_ROUTER_TEMPLATE = \"\"\"给语言模型一个原始文本输入,\\\n", + "让其选择最适合输入的模型提示。\\\n", + "系统将为您提供可用提示的名称以及最适合改提示的描述。\\\n", + "如果你认为修改原始输入最终会导致语言模型做出更好的响应,\\\n", + "你也可以修改原始输入。\n", + "\n", + "\n", + "<< 格式 >>\n", + "返回一个带有JSON对象的markdown代码片段,该JSON对象的格式如下:\n", + "```json\n", + "{{{{\n", + " \"destination\": 字符串 \\ 使用的提示名字或者使用 \"DEFAULT\"\n", + " \"next_inputs\": 字符串 \\ 原始输入的改进版本\n", + "}}}}\n", + "```\n", + "\n", + "\n", + "记住:“destination”必须是下面指定的候选提示名称之一,\\\n", + "或者如果输入不太适合任何候选提示,\\\n", + "则可以是 “DEFAULT” 。\n", + "记住:如果您认为不需要任何修改,\\\n", + "则 “next_inputs” 可以只是原始输入。\n", + "\n", + "<< 候选提示 >>\n", + "{destinations}\n", + "\n", + "<< 输入 >>\n", + "{{input}}\n", + "\n", + "<< 输出 (记得要包含 ```json)>>\n", + "\n", + "样例:\n", + "<< 输入 >>\n", + "\"什么是黑体辐射?\"\n", + "<< 输出 >>\n", + "```json\n", + "{{{{\n", + " \"destination\": 字符串 \\ 使用的提示名字或者使用 \"DEFAULT\"\n", + " \"next_inputs\": 字符串 \\ 原始输入的改进版本\n", + "}}}}\n", + "```\n", + "\n", + "\"\"\"" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "de5c46d0", "metadata": {}, @@ -1028,7 +1364,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 34, "id": "1387109d", "metadata": {}, "outputs": [], @@ -1046,6 +1382,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "7e92355c", "metadata": {}, @@ -1055,7 +1392,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 35, "id": "2fb7d560", "metadata": {}, "outputs": [], @@ -1069,6 +1406,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "086503f7", "metadata": {}, @@ -1077,6 +1415,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "969cd878", "metadata": {}, @@ -1086,8 +1425,8 @@ }, { "cell_type": "code", - "execution_count": 21, - "id": "d86b2131", + "execution_count": null, + "id": "2217d987", "metadata": {}, "outputs": [ { @@ -1107,9 +1446,8 @@ "'Black body radiation is the electromagnetic radiation emitted by a perfect black body, which absorbs all incident radiation and reflects none. It is characterized by a continuous spectrum of radiated energy that is dependent on the temperature of the body, with higher temperatures leading to more intense and shorter wavelength radiation. This phenomenon is an important concept in thermal physics and has numerous applications, ranging from understanding stellar spectra to designing artificial light sources.'" ] }, - "execution_count": 21, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -1119,7 +1457,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 36, "id": "4446724c", "metadata": {}, "outputs": [ @@ -1130,27 +1468,61 @@ "\n", "\n", "\u001b[1m> Entering new MultiPromptChain chain...\u001b[0m\n", - "physics: {'input': 'What is a black hole made of?'}\n", + "physics: {'input': '什么是黑体辐射?'}\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ - "'A black hole is not made of any material substance that we know of. It is formed by the collapse of a massive object, such as a star, into an infinitely small point called a singularity. This singularity has infinite density and gravity, and is surrounded by an event horizon, which is the point of no return for anything that gets too close to the black hole. So, in essence, a black hole is made of nothing but gravity.'" + "'黑体辐射是指一个理想化的物体,它能够完全吸收所有入射到它表面的辐射能量,并以热辐射的形式重新发射出来。黑体辐射的特点是其辐射能量的分布与温度有关,随着温度的升高,辐射能量的峰值会向更短的波长方向移动。这个现象被称为黑体辐射谱的位移定律,由普朗克在20世纪初提出。黑体辐射在研究热力学、量子力学和宇宙学等领域中具有重要的应用。'" ] }, - "execution_count": 24, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#中文\n", - "chain.run(\"黑洞是种什么物质?\")" + "chain.run(\"什么是黑体辐射?\")" ] }, { + "cell_type": "code", + "execution_count": 41, + "id": "ef81eda3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new MultiPromptChain chain...\u001b[0m\n", + "History: {'input': '你知道李白是谁嘛?'}\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'李白是唐朝时期的一位著名诗人。他的诗歌以豪放、奔放、自由的风格著称,被誉为“诗仙”。他的作品涉及广泛,包括山水田园、历史传说、哲理思考等多个方面,对中国古典文学的发展产生了深远的影响。'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 中文\n", + "chain.run(\"你知道李白是谁嘛?\")" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "289c5ca9", "metadata": {}, @@ -1192,6 +1564,54 @@ ] }, { + "cell_type": "code", + "execution_count": 37, + "id": "795bea17", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new MultiPromptChain chain...\u001b[0m\n", + "math: {'input': '2 + 2 等于多少'}" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 1.0 seconds as it raised ServiceUnavailableError: The server is overloaded or not ready yet..\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'2 + 2 等于 4。'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 中文\n", + "chain.run(\"2 + 2 等于多少\")" + ] + }, + { + "attachments": {}, "cell_type": "markdown", "id": "4186a2b9", "metadata": {}, @@ -1236,8 +1656,8 @@ }, { "cell_type": "code", - "execution_count": 41, - "id": "ef81eda3", + "execution_count": 38, + "id": "a64d0759", "metadata": {}, "outputs": [ { @@ -1247,24 +1667,24 @@ "\n", "\n", "\u001b[1m> Entering new MultiPromptChain chain...\u001b[0m\n", - "History: {'input': '你知道李白是谁嘛?'}\n", + "None: {'input': '为什么我们身体里的每个细胞都包含DNA?'}\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ - "'李白是唐朝时期的一位著名诗人。他的诗歌以豪放、奔放、自由的风格著称,被誉为“诗仙”。他的作品涉及广泛,包括山水田园、历史传说、哲理思考等多个方面,对中国古典文学的发展产生了深远的影响。'" + "'我们身体里的每个细胞都包含DNA,是因为DNA是遗传信息的载体。DNA是由四种碱基(腺嘌呤、鸟嘌呤、胸腺嘧啶和鳞嘌呤)组成的长链状分子,它存储了生物体的遗传信息,包括个体的特征、生长发育、代谢功能等。每个细胞都需要这些遗传信息来执行其特定的功能和任务,因此每个细胞都需要包含DNA。此外,DNA还能通过复制和传递给下一代细胞和个体,以保证遗传信息的传承。'" ] }, - "execution_count": 41, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 中文\n", - "chain.run(\"你知道李白是谁嘛?\")" + "chain.run(\"为什么我们身体里的每个细胞都包含DNA?\")" ] } ], @@ -1284,25 +1704,7 @@ "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": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": true, - "toc_position": { - "height": "calc(100% - 180px)", - "left": "10px", - "top": "150px", - "width": "261.818px" - }, - "toc_section_display": true, - "toc_window_display": true + "version": "3.10.9" } }, "nbformat": 4,