{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# chat 和 service 接口的示例用法\n",
    "这个笔记本展示了 MemoryScope 的 **chat** 和 **service** 接口的简单用法,以及它的主要功能。\n",
    "\n",
    "在运行这个笔记本之前,请先按照 Readme 中的 [**Installation**](../../docs/installation_zh.md#三通过-pypi-安装) 指南进行安装,并启动 Docker 镜像。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 初始化一个 MemoryScope 实例\n",
    "首先,我们需要指定一个配置并初始化一个 MemoryScope 实例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from memoryscope import MemoryScope, Arguments\n",
    "arguments = Arguments(\n",
    "    language=\"cn\",\n",
    "    human_name=\"用户\",\n",
    "    assistant_name=\"AI\",\n",
    "    memory_chat_class=\"api_memory_chat\",\n",
    "    generation_backend=\"dashscope_generation\",\n",
    "    generation_model=\"qwen-max\",\n",
    "    embedding_backend=\"dashscope_embedding\",\n",
    "    embedding_model=\"text-embedding-v2\",\n",
    "    rank_backend=\"dashscope_rank\",\n",
    "    rank_model=\"gte-rerank\",\n",
    "    enable_ranker=True)\n",
    "\n",
    "ms = MemoryScope(arguments=arguments)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 聊天(不含记忆)\n",
    "MemoryScope 配有默认的 chat 接口,因此开始聊天非常容易,就像使用任何大型语言模型聊天机器人一样。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答1:\n",
      "很高兴了解到您的爱好是弹琴,这是一种既能陶冶情操又能提升音乐技能的美妙艺术形式。无论是古典钢琴、爵士乐还是现代流行曲目,每一种风格都能带来不同的享受和挑战。希望您在弹琴的过程中能够持续发现乐趣,创造出更多动人的旋律。\n"
     ]
    }
   ],
   "source": [
    "memory_chat = ms.default_memory_chat\n",
    "memory_chat.run_service_operation(\"delete_all\")\n",
    "response = memory_chat.chat_with_memory(query=\"我的爱好是弹琴。\")\n",
    "print(\"回答1:\\n\" + response.message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "你可以选择进行含有或不含有多轮对话上下文的聊天。然而,由于尚未调用**记忆巩固**功能,系统中还没有任何记忆片段。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答2:\n",
      "是的,您提到过您的爱好是弹琴,所以我认为您对键盘乐器,特别是钢琴有一定的爱好。\n",
      "回答3:\n",
      "作为基于当前对话的MemoryScope智能助理,我没有之前关于您乐器爱好的信息。请告诉我,您喜欢哪种乐器?这样我就可以记住并提供相关帮助了。\n"
     ]
    }
   ],
   "source": [
    "response = memory_chat.chat_with_memory(query=\"你知道我有什么乐器爱好吗?\")\n",
    "print(\"回答2:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"你知道我有什么乐器爱好吗?\",\n",
    "                                        history_message_strategy=None)\n",
    "print(\"回答3:\\n\" + response.message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **记忆巩固**\n",
    "现在,我们再聊多几句,然后尝试**记忆巩固**功能。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答4:\n",
      "了解,您在阿里巴巴工作。阿里巴巴集团是一家总部位于中国杭州的全球领先的电子商务和科技公司,以其电子商务平台如淘宝、天猫闻名,同时在云计算、数字媒体及娱乐、金融科技等领域也有广泛布局。如果您有关于工作、技术或公司文化方面的问题,欢迎随时询问。\n",
      "回答5:\n",
      "选择水果可以根据个人口味、营养需求以及季节来决定。夏天,一些清爽解暑的水果会是不错的选择,比如西瓜、哈密瓜、葡萄、桃子或者李子,它们都含有丰富的水分和维生素,有助于消暑降温。如果您想要补充纤维素,火龙果或者猕猴桃也是很好的选择。最终,选择哪种水果,还是要看您自己的喜好和身体状况。\n",
      "回答6:\n",
      "西瓜是夏季的理想选择,它不仅清凉解渴,还含有大量的水分和电解质,可以帮助身体补充流失的水分。西瓜还富含维生素C、A和抗氧化剂,如番茄红素,对皮肤健康和心血管系统都有益处。享用美味的西瓜时,记得切块后冷藏一下,口感会更加清爽哦!\n",
      "回答7:\n",
      "\"生日快乐,愿你的每一天都如蛋糕般甜蜜,笑容比烛光更灿烂!\"\n"
     ]
    }
   ],
   "source": [
    "response = memory_chat.chat_with_memory(query=\"我在阿里巴巴干活\")\n",
    "print(\"回答4:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"今天下午吃什么水果好?\")\n",
    "print(\"回答5:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我喜欢吃西瓜。\")\n",
    "print(\"回答6:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"帮我写一句给朋友的生日祝福语,简短一点。\")\n",
    "print(\"回答7:\\n\" + response.message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "consolidate_memory result=[MEMORY ACTIONS]:\n",
      "new observation: 用户爱好弹琴。 (valid)\n",
      "new observation: 用户在阿里巴巴工作。 (valid)\n",
      "new observation: 用户喜欢吃西瓜。 (valid)\n"
     ]
    }
   ],
   "source": [
    "memory_service = ms.default_memory_service\n",
    "memory_service.init_service()\n",
    "result = memory_service.consolidate_memory()\n",
    "print(f\"consolidate_memory result={result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "**记忆巩固**从用户的7条聊天消息中提取了3条 *observations* ,其余无效的信息被过滤掉了。\n",
    "\n",
    "我们尝试更多的情况,以测试其时间感知能力和过滤用户虚构的内容的能力。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答8:\n",
      "京东作为中国领先的电商平台之一,拥有广泛的业务范围和良好的行业声誉。加入京东工作,您可能会享受到以下几方面的前景优势:\n",
      "\n",
      "1. **职业发展**:京东提供多元化的职业路径和晋升机会,您可以在电商、物流、科技、金融等多个领域找到适合自己的位置和发展空间。\n",
      "\n",
      "2. **技术与创新**:京东持续投入于技术创新,尤其是在人工智能、大数据、云计算等方面,为员工提供了接触和学习前沿技术的机会。\n",
      "\n",
      "3. **企业文化**:京东强调“正道成功”的企业文化,注重诚信、团队合作与社会责任,有利于塑造积极向上的工作氛围。\n",
      "\n",
      "4. **福利待遇**:京东通常为员工提供有竞争力的薪酬福利体系,包括但不限于健康保险、员工培训、股权激励等。\n",
      "\n",
      "5. **行业影响力**:作为行业巨头,京东的从业经历对您的职业生涯将是一大亮点,有助于提升个人品牌和未来的职业选择灵活性。\n",
      "\n",
      "当然,具体前景还取决于您的职位、个人能力、行业趋势及个人职业规划等因素。建议您深入了解目标岗位的具体要求,评估个人与岗位的匹配度,并关注行业动态,为自己的职业发展做出合理规划。\n",
      "回答9:\n",
      "好的,已记录您计划下周去北京出差。请随时告诉我如果您需要关于北京的出行建议、天气预报或是其他相关信息。祝您出差顺利!\n",
      "回答10:\n",
      "已记录您的安排,您将于下个月与在亚马逊工作的同学李亚平在上海共进晚餐。临近日期时,不妨提前联系李亚平确认具体时间和地点,以便愉快地进行聚会。希望你们有个美好的重聚!\n",
      "回答11:\n",
      "【场景:傍晚,公园长椅】  \n",
      "小亮是我最好的朋友,他决定去山西上大学。夕阳下,我们肩并肩坐着。  \n",
      "我:“山西的面食可出名了,你这小吃货有福了!”  \n",
      "小亮笑:“那必须的,说好你放假就来找我,咱们一起吃遍山西!”  \n",
      "我点头,心中泛起不舍:“一言为定,别忘了,那里还有千年古城等你探索。”  \n",
      "小亮看向远方,眼里闪烁着梦想的光:“新旅程,我们一起加油!”  \n",
      "【画面渐暗,友情的力量温暖而坚定】\n",
      "回答12:\n",
      "SMCI可能指代的是Super Micro Computer, Inc.(超微电脑股份有限公司),简称Supermicro。这是一家总部位于美国加利福尼亚州圣何塞的公司,成立于1993年。Supermicro主要设计、制造和销售高性能服务器和技术解决方案,包括服务器、存储系统、主板以及支持云计算、数据中心、企业IT、高性能计算(HPC)和嵌入式系统的其他硬件组件。它们的产品以高效率、灵活性和定制化选项著称,在全球范围内服务于各种规模的企业和组织。\n"
     ]
    }
   ],
   "source": [
    "response = memory_chat.chat_with_memory(query=\"假如我去京东工作,前景怎么样?\")\n",
    "print(\"回答8:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"记一下,下周我准备去北京出差\")\n",
    "print(\"回答9:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我同学李亚平现在在亚马逊工作,他下个月回上海,我要和他吃个饭\")\n",
    "print(\"回答10:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"小亮是我最好的朋友,他决定去山西上大学。以这个为开头写一个80字的微剧本。\")\n",
    "print(\"回答11:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"SMCI是什么公司,做什么的?\")\n",
    "print(\"回答12:\\n\" + response.message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "consolidate_memory result=[MEMORY ACTIONS]:\n",
      "new observation: 用户计划2024年8月9日去北京出差。 (推断时间: 2024年8月9日) (valid)\n",
      "new observation: 用户的同学李亚平下个月回上海,用户将与其见面吃饭。 (推断时间: 2024年9月) (valid)\n"
     ]
    }
   ],
   "source": [
    "result = memory_service.consolidate_memory()\n",
    "print(f\"consolidate_memory result={result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "我们可以看到,**记忆巩固**成功过滤掉了虚假内容,并展示了良好的时间敏感性。\n",
    "\n",
    "我们尝试更多的情况,以测试其解决冲突内容的能力。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答13:\n",
      "既然您喜欢吃西瓜,今天下午吃西瓜是个不错的选择。\n",
      "回答14:\n",
      "那太好了,如果您今天想换换口味,吃芒果也是很好的选择,享受它的香甜吧!\n",
      "回答15:\n",
      "恭喜您加入美团!希望您的新工作一切顺利,有新的挑战和机遇。\n",
      "回答16:\n",
      "了解了,桃子和苹果都是既营养又美味的选择,多吃水果对身体有益,您可以根据季节和个人喜好来挑选。\n",
      "回答17:\n",
      "好的,知道您不喜欢椰子,以后在推荐水果时会留意这一点。\n",
      "回答18:\n",
      "听起来很有趣!去海南冲浪是个很棒的计划,下个月那边的天气应该很适合水上活动,祝您玩得开心!别忘了做好防晒哦。\n",
      "回答19:\n",
      "生日快乐!希望您明天能度过一个特别且难忘的一天,满满的祝福给您!有任何庆祝计划吗?\n"
     ]
    }
   ],
   "source": [
    "response = memory_chat.chat_with_memory(query=\"今天下午吃什么水果好?\")\n",
    "print(\"回答13:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"西瓜确实不错,但是我也喜欢吃芒果。我今天想吃芒果。\")\n",
    "print(\"回答14:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我最近跳槽去了美团。\")\n",
    "print(\"回答15:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我还喜欢吃桃子和苹果。\")\n",
    "print(\"回答16:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我不喜欢吃椰子。\")\n",
    "print(\"回答17:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"我准备下个月去海南冲浪。\")\n",
    "print(\"回答18:\\n\" + response.message.content)\n",
    "response = memory_chat.chat_with_memory(query=\"明天是我生日。\")\n",
    "print(\"回答19:\\n\" + response.message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "consolidate_memory result=[MEMORY ACTIONS]:\n",
      "new observation: 用户喜欢吃桃子和苹果。 (valid)\n",
      "new observation: 用户不喜欢吃椰子。 (valid)\n",
      "new observation: 用户喜欢吃芒果。 (valid)\n",
      "new observation: 用户计划2024年9月去海南冲浪。 (推断时间: 2024年9月) (valid)\n",
      "new observation: 用户的生日是每年8月3日。 (推断时间: 每年8月3日) (valid)\n",
      "modified observation: 用户在阿里巴巴工作。 (expired)\n",
      "modified observation: 用户最近跳槽至美团。 (expired)\n"
     ]
    }
   ],
   "source": [
    "result = memory_service.consolidate_memory()\n",
    "print(f\"consolidate_memory result={result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **反思与再巩固**\n",
    "现在,我们在系统中已经积累了足够多的新的 *observations* ,因此我们可以调用**反思与再巩固**功能,让我们看看会得到什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "consolidate_memory result=[MEMORY ACTIONS]:\n",
      "new insight: 用户的出差计划: 2024年8月9日去北京出差 (valid)\n",
      "new insight: 用户的生日: 每年8月3日 (valid)\n",
      "new insight: 用户的水果偏好: 喜欢桃子、苹果、西瓜、芒果,不喜欢吃椰子 (valid)\n",
      "modified observation: 用户计划2024年8月9日去北京出差。 (推断时间: 2024年8月9日) (valid)\n",
      "modified observation: 用户的生日是每年8月3日。 (推断时间: 每年8月3日) (valid)\n",
      "modified observation: 用户计划2024年9月去海南冲浪。 (推断时间: 2024年9月) (valid)\n",
      "modified observation: 用户喜欢吃芒果。 (valid)\n",
      "modified observation: 用户喜欢吃桃子和苹果。 (valid)\n",
      "modified observation: 用户爱好弹琴。 (valid)\n",
      "modified observation: 用户喜欢吃西瓜。 (valid)\n",
      "modified observation: 用户不喜欢吃椰子。 (valid)\n",
      "modified observation: 用户的同学李亚平下个月回上海,用户将与其见面吃饭。 (推断时间: 2024年9月) (valid)\n"
     ]
    }
   ],
   "source": [
    "result = memory_service.reflect_and_reconsolidate()\n",
    "print(f\"consolidate_memory result={result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 低用户时延(RT)\n",
    "\n",
    "最后,我们测试 MemoryScope 系统对用户的响应时间 (RT)。具体来说,我们测试在有和没有从系统中检索记忆片段时聊天的响应时间的差异。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "start_time = time.time()\n",
    "response = memory_chat.chat_with_memory(query=\"你知道我的乐器爱好是什么吗?\",\n",
    "                                        history_message_strategy=None)\n",
    "end_time = time.time()\n",
    "total_time = end_time - start_time\n",
    "print(\"使用记忆检索\\n回答20:\\n\" + response.message.content + f\"\\n 耗时:{total_time}秒\\n\")\n",
    "\n",
    "start_time = time.time()\n",
    "response = memory_chat.chat_with_memory(query=\"你知道我接下去的一个月内有什么计划吗?\",\n",
    "                                        history_message_strategy=None)\n",
    "end_time = time.time()\n",
    "total_time = end_time - start_time\n",
    "print(\"使用记忆检索\\n回答21:\\n\" + response.message.content + f\"\\n 耗时:{total_time}秒\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "使用记忆检索\n",
      "回答20:\n",
      "您喜欢弹琴。\n",
      " 耗时:1.3783161640167236秒\n",
      "\n",
      "使用记忆检索\n",
      "回答21:\n",
      "您接下来一个月内的计划包括:\n",
      "- 2024年8月9日去北京出差。\n",
      "- 计划在2024年9月去海南冲浪。\n",
      "- 2024年9月,您的同学李亚平回上海,您将与他见面吃饭。\n",
      " 耗时:6.538439035415649秒\n",
      "\n",
      "不使用记忆检索\n",
      "回答20:\n",
      "对不起,我没有记录您的个人信息,包括您的乐器爱好。如果您告诉我,我可以帮您记住。\n",
      " 耗时:2.597784996032715秒\n",
      "\n",
      "不使用记忆检索\n",
      "回答21:\n",
      "对不起,作为基于当前会话的MemoryScope智能助理,我无法获取或存储您的个人日程信息。如果您需要查询自己的计划,建议您查看自己的日历或者备忘录。\n",
      " 耗时:5.246160984039307秒\n"
     ]
    }
   ],
   "source": [
    "memory_chat.run_service_operation(\"delete_all\")\n",
    "start_time = time.time()\n",
    "response = memory_chat.chat_with_memory(query=\"你知道我的乐器爱好是什么吗?\",\n",
    "                                        history_message_strategy=None)\n",
    "end_time = time.time()\n",
    "total_time = end_time - start_time\n",
    "print(\"不使用记忆检索\\n回答20:\\n\" + response.message.content + f\"\\n 耗时:{total_time}秒\\n\")\n",
    "\n",
    "start_time = time.time()\n",
    "response = memory_chat.chat_with_memory(query=\"你知道我接下去的一个月内有什么计划吗?\\n\",\n",
    "                                        history_message_strategy=None)\n",
    "end_time = time.time()\n",
    "total_time = end_time - start_time\n",
    "print(\"不使用记忆检索\\n回答21:\\n\" + response.message.content + f\"\\n 耗时:{total_time}秒\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "我们可以看到,从 MemoryScope 检索记忆片段不会增加聊天的响应时间。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 更多用法\n",
    "我们建议读者参考[进阶自定义用法](../advance/custom_operator_zh.md)来对MemoryScope系统进行各种自定义设置。您还可以通过自定义**workflow**和对应的**worker**来创建或定制满足您特定需求的**operation**。\n",
    "\n",
    "此外,您还可以尝试使用[在命令行与MemoryScope聊天机器人交互](../cli/CLI_README_ZH.md)。我们在这里实现了始终在后台异步运行**记忆巩固**和**反思与再巩固**这两个操作,从而使得它们不会增加聊天的响应时间。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}