{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# L4: 处理输入: 思维链推理"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在本节中，我们将专注于处理输入的任务，即通过一系列步骤生成有用输出的任务。\n",
    "\n",
    "有时，模型在回答特定问题之前需要详细推理问题，如果您参加了我们之前的课程，您将看到许多这样的例子。有时，模型可能会通过匆忙得出错误的结论而出现推理错误，因此我们可以重新构思查询，要求模型在提供最终答案之前提供一系列相关的推理步骤，以便它可以更长时间、更有方法地思考问题。\n",
    "\n",
    "通常，我们称这种要求模型逐步推理问题的策略为思维链推理。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 设置\n",
    "#### 加载 API key 和相关的 Python 库.\n",
    "在这门课程中，我们提供了一些代码，帮助你加载OpenAI API key。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import openai\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "_ = load_dotenv(find_dotenv()) # read local .env file\n",
    "\n",
    "openai.api_key  = os.environ['OPENAI_API_KEY']\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_completion_from_messages(messages, \n",
    "                                 model=\"gpt-3.5-turbo\", \n",
    "                                 temperature=0, \n",
    "                                 max_tokens=500):\n",
    "    response = openai.ChatCompletion.create(\n",
    "        model=model,\n",
    "        messages=messages,\n",
    "        temperature=temperature, \n",
    "        max_tokens=max_tokens, \n",
    "    )\n",
    "    return response.choices[0].message[\"content\"]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 思维链提示"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因此，我们在这里要求模型在得出结论之前推理答案。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "delimiter = \"####\"\n",
    "system_message = f\"\"\"\n",
    "Follow these steps to answer the customer queries.\n",
    "The customer query will be delimited with four hashtags,\\\n",
    "i.e. {delimiter}. \n",
    "\n",
    "Step 1:{delimiter} First decide whether the user is \\\n",
    "asking a question about a specific product or products. \\\n",
    "Product cateogry doesn't count. \n",
    "\n",
    "Step 2:{delimiter} If the user is asking about \\\n",
    "specific products, identify whether \\\n",
    "the products are in the following list.\n",
    "All available products: \n",
    "1. Product: TechPro Ultrabook\n",
    "   Category: Computers and Laptops\n",
    "   Brand: TechPro\n",
    "   Model Number: TP-UB100\n",
    "   Warranty: 1 year\n",
    "   Rating: 4.5\n",
    "   Features: 13.3-inch display, 8GB RAM, 256GB SSD, Intel Core i5 processor\n",
    "   Description: A sleek and lightweight ultrabook for everyday use.\n",
    "   Price: $799.99\n",
    "\n",
    "2. Product: BlueWave Gaming Laptop\n",
    "   Category: Computers and Laptops\n",
    "   Brand: BlueWave\n",
    "   Model Number: BW-GL200\n",
    "   Warranty: 2 years\n",
    "   Rating: 4.7\n",
    "   Features: 15.6-inch display, 16GB RAM, 512GB SSD, NVIDIA GeForce RTX 3060\n",
    "   Description: A high-performance gaming laptop for an immersive experience.\n",
    "   Price: $1199.99\n",
    "\n",
    "3. Product: PowerLite Convertible\n",
    "   Category: Computers and Laptops\n",
    "   Brand: PowerLite\n",
    "   Model Number: PL-CV300\n",
    "   Warranty: 1 year\n",
    "   Rating: 4.3\n",
    "   Features: 14-inch touchscreen, 8GB RAM, 256GB SSD, 360-degree hinge\n",
    "   Description: A versatile convertible laptop with a responsive touchscreen.\n",
    "   Price: $699.99\n",
    "\n",
    "4. Product: TechPro Desktop\n",
    "   Category: Computers and Laptops\n",
    "   Brand: TechPro\n",
    "   Model Number: TP-DT500\n",
    "   Warranty: 1 year\n",
    "   Rating: 4.4\n",
    "   Features: Intel Core i7 processor, 16GB RAM, 1TB HDD, NVIDIA GeForce GTX 1660\n",
    "   Description: A powerful desktop computer for work and play.\n",
    "   Price: $999.99\n",
    "\n",
    "5. Product: BlueWave Chromebook\n",
    "   Category: Computers and Laptops\n",
    "   Brand: BlueWave\n",
    "   Model Number: BW-CB100\n",
    "   Warranty: 1 year\n",
    "   Rating: 4.1\n",
    "   Features: 11.6-inch display, 4GB RAM, 32GB eMMC, Chrome OS\n",
    "   Description: A compact and affordable Chromebook for everyday tasks.\n",
    "   Price: $249.99\n",
    "\n",
    "Step 3:{delimiter} If the message contains products \\\n",
    "in the list above, list any assumptions that the \\\n",
    "user is making in their \\\n",
    "message e.g. that Laptop X is bigger than \\\n",
    "Laptop Y, or that Laptop Z has a 2 year warranty.\n",
    "\n",
    "Step 4:{delimiter}: If the user made any assumptions, \\\n",
    "figure out whether the assumption is true based on your \\\n",
    "product information. \n",
    "\n",
    "Step 5:{delimiter}: First, politely correct the \\\n",
    "customer's incorrect assumptions if applicable. \\\n",
    "Only mention or reference products in the list of \\\n",
    "5 available products, as these are the only 5 \\\n",
    "products that the store sells. \\\n",
    "Answer the customer in a friendly tone.\n",
    "\n",
    "Use the following format:\n",
    "Step 1:{delimiter} <step 1 reasoning>\n",
    "Step 2:{delimiter} <step 2 reasoning>\n",
    "Step 3:{delimiter} <step 3 reasoning>\n",
    "Step 4:{delimiter} <step 4 reasoning>\n",
    "Response to user:{delimiter} <response to customer>\n",
    "\n",
    "Make sure to include {delimiter} to separate every step.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step 1:#### The user is asking a question about two specific products, the BlueWave Chromebook and the TechPro Desktop.\n",
      "Step 2:#### The prices of the two products are as follows:\n",
      "- BlueWave Chromebook: $249.99\n",
      "- TechPro Desktop: $999.99\n",
      "Step 3:#### The user is assuming that the BlueWave Chromebook is more expensive than the TechPro Desktop.\n",
      "Step 4:#### The assumption is incorrect. The TechPro Desktop is actually more expensive than the BlueWave Chromebook.\n",
      "Response to user:#### The BlueWave Chromebook is actually less expensive than the TechPro Desktop. The BlueWave Chromebook costs $249.99 while the TechPro Desktop costs $999.99.\n"
     ]
    }
   ],
   "source": [
    "user_message = f\"\"\"\n",
    "by how much is the BlueWave Chromebook more expensive \\\n",
    "than the TechPro Desktop\"\"\"\n",
    "\n",
    "messages =  [  \n",
    "{'role':'system', \n",
    " 'content': system_message},    \n",
    "{'role':'user', \n",
    " 'content': f\"{delimiter}{user_message}{delimiter}\"},  \n",
    "] \n",
    "\n",
    "response = get_completion_from_messages(messages)\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step 1:#### The user is asking if the store sells TVs.\n",
      "Step 2:#### The list of available products does not include any TVs.\n",
      "Response to user:#### I'm sorry, but we do not sell TVs at this store. Our available products include computers and laptops.\n"
     ]
    }
   ],
   "source": [
    "user_message = f\"\"\"\n",
    "do you sell tvs\"\"\"\n",
    "messages =  [  \n",
    "{'role':'system', \n",
    " 'content': system_message},    \n",
    "{'role':'user', \n",
    " 'content': f\"{delimiter}{user_message}{delimiter}\"},  \n",
    "] \n",
    "response = get_completion_from_messages(messages)\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "delimiter = \"####\"\n",
    "system_message = f\"\"\"\n",
    "请按照以下步骤回答客户的查询。客户的查询将以四个井号（#）分隔，即 {delimiter}。\n",
    "\n",
    "步骤 1:{delimiter} 首先确定用户是否正在询问有关特定产品或产品的问题。产品类别不计入范围。\n",
    "\n",
    "步骤 2:{delimiter} 如果用户询问特定产品，请确认产品是否在以下列表中。所有可用产品：\n",
    "\n",
    "产品：TechPro超极本\n",
    "类别：计算机和笔记本电脑\n",
    "品牌：TechPro\n",
    "型号：TP-UB100\n",
    "保修期：1年\n",
    "评分：4.5\n",
    "特点：13.3英寸显示屏，8GB RAM，256GB SSD，Intel Core i5处理器\n",
    "描述：一款适用于日常使用的时尚轻便的超极本。\n",
    "价格：$799.99\n",
    "\n",
    "产品：BlueWave游戏笔记本电脑\n",
    "类别：计算机和笔记本电脑\n",
    "品牌：BlueWave\n",
    "型号：BW-GL200\n",
    "保修期：2年\n",
    "评分：4.7\n",
    "特点：15.6英寸显示屏，16GB RAM，512GB SSD，NVIDIA GeForce RTX 3060\n",
    "描述：一款高性能的游戏笔记本电脑，提供沉浸式体验。\n",
    "价格：$1199.99\n",
    "\n",
    "产品：PowerLite可转换笔记本电脑\n",
    "类别：计算机和笔记本电脑\n",
    "品牌：PowerLite\n",
    "型号：PL-CV300\n",
    "保修期：1年\n",
    "评分：4.3\n",
    "特点：14英寸触摸屏，8GB RAM，256GB SSD，360度铰链\n",
    "描述：一款多功能可转换笔记本电脑，具有响应触摸屏。\n",
    "价格：$699.99\n",
    "\n",
    "产品：TechPro台式电脑\n",
    "类别：计算机和笔记本电脑\n",
    "品牌：TechPro\n",
    "型号：TP-DT500\n",
    "保修期：1年\n",
    "评分：4.4\n",
    "特点：Intel Core i7处理器，16GB RAM，1TB HDD，NVIDIA GeForce GTX 1660\n",
    "描述：一款功能强大的台式电脑，适用于工作和娱乐。\n",
    "价格：$999.99\n",
    "\n",
    "产品：BlueWave Chromebook\n",
    "类别：计算机和笔记本电脑\n",
    "品牌：BlueWave\n",
    "型号：BW-CB100\n",
    "保修期：1年\n",
    "评分：4.1\n",
    "特点：11.6英寸显示屏，4GB RAM，32GB eMMC，Chrome OS\n",
    "描述：一款紧凑而价格实惠的Chromebook，适用于日常任务。\n",
    "价格：$249.99\n",
    "\n",
    "步骤 3:{delimiter} 如果消息中包含上述列表中的产品，请列出用户在消息中做出的任何假设，例如笔记本电脑 X 比笔记本电脑 Y 大，或者笔记本电脑 Z 有 2 年保修期。\n",
    "\n",
    "步骤 4:{delimiter} 如果用户做出了任何假设，请根据产品信息确定假设是否正确。\n",
    "\n",
    "步骤 5:{delimiter} 如果用户有任何错误的假设，请先礼貌地纠正客户的错误假设（如果适用）。只提及或引用可用产品列表中的产品，因为这是商店销售的唯一五款产品。以友好的口吻回答客户。\n",
    "\n",
    "使用以下格式回答问题：\n",
    "步骤 1:{delimiter} <步骤 1的推理>\n",
    "步骤 2:{delimiter} <步骤 2 的推理>\n",
    "步骤 3:{delimiter} <步骤 3 的推理>\n",
    "步骤 4:{delimiter} <步骤 4 的推理>\n",
    "回复客户:{delimiter} <回复客户的内容>\n",
    "\n",
    "请确保在每个步骤之间使用 {delimiter} 进行分隔。\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "步骤 1:#### 确认用户正在询问有关特定产品的问题。\n",
      "\n",
      "步骤 2:#### 用户询问 BlueWave Chromebook 和 TechPro 台式电脑之间的价格差异。\n",
      "\n",
      "步骤 3:#### 用户假设 BlueWave Chromebook 的价格高于 TechPro 台式电脑。\n",
      "\n",
      "步骤 4:#### 用户的假设是正确的。BlueWave Chromebook 的价格为 $249.99，而 TechPro 台式电脑的价格为 $999.99，因此 BlueWave Chromebook 的价格比 TechPro 台式电脑低 $750。\n",
      "\n",
      "回复客户:#### BlueWave Chromebook 比 TechPro 台式电脑便宜 $750。\n"
     ]
    }
   ],
   "source": [
    "user_message = f\"\"\"BlueWave Chromebook 比 TechPro 台式电脑贵多少？\"\"\"\n",
    "\n",
    "messages =  [  \n",
    "{'role':'system', \n",
    " 'content': system_message},    \n",
    "{'role':'user', \n",
    " 'content': f\"{delimiter}{user_message}{delimiter}\"},  \n",
    "] \n",
    "\n",
    "response = get_completion_from_messages(messages)\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "步骤 1:#### 首先确定用户是否正在询问有关特定产品或产品的问题。产品类别不计入范围。\n",
      "\n",
      "步骤 2:#### 如果用户询问特定产品，请确认产品是否在以下列表中。所有可用产品：\n",
      "\n",
      "我们很抱歉，我们商店不出售电视机。\n",
      "\n",
      "步骤 3:#### 如果消息中包含上述列表中的产品，请列出用户在消息中做出的任何假设，例如笔记本电脑 X 比笔记本电脑 Y 大，或者笔记本电脑 Z 有 2 年保修期。\n",
      "\n",
      "N/A\n",
      "\n",
      "步骤 4:#### 如果用户做出了任何假设，请根据产品信息确定假设是否正确。\n",
      "\n",
      "N/A\n",
      "\n",
      "回复客户:#### 我们很抱歉，我们商店不出售电视机。\n"
     ]
    }
   ],
   "source": [
    "user_message = f\"\"\"你有电视机么\"\"\"\n",
    "messages =  [  \n",
    "{'role':'system', \n",
    " 'content': system_message},    \n",
    "{'role':'user', \n",
    " 'content': f\"{delimiter}{user_message}{delimiter}\"},  \n",
    "] \n",
    "response = get_completion_from_messages(messages)\n",
    "print(response)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 内心独白"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于某些应用程序，模型用于得出最终答案的推理过程可能不适合与用户共享。例如，在辅导应用程序中，我们可能希望鼓励学生自己解决问题，但模型对学生解决方案的推理过程可能会揭示答案。\n",
    "\n",
    "内心独白是一种可以用来缓解这种情况的策略，这只是一种隐藏模型推理过程的高级方法。\n",
    "\n",
    "内心独白的想法是指示模型将输出的部分放在不会透露答案的方式中，以便用户无法看到完整的推理过程。旨在将它们隐藏在一个结构化的格式中，使得传递它们变得容易。然后，在向用户呈现输出之前，输出被传递，只有部分输出是可见的。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我们很抱歉，我们商店不出售电视机。\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    final_response = response.split(delimiter)[-1].strip()\n",
    "except Exception as e:\n",
    "    final_response = \"Sorry, I'm having trouble right now, please try asking another question.\"\n",
    "    \n",
    "print(final_response)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.10.11"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
