易速鲜花聊天客服机器人的开发(上)

“聊天机器人”项目说明

聊天机器人(Chatbot)是LLM和LangChain的核心用例之一,很多人学习大语言模型,学习LangChain,就是为了开发出更好的、更能理解用户意图的聊天机器人。聊天机器人的核心特征是,它们可以进行长时间的对话并访问用户想要了解的信息。

如图所示,聊天机器人设计过程中的核心组件包括:

  • 聊天模型:这是对话的基础,它更偏向于自然的对话风格。你可以参考LangChain相关文档中所支持的聊天模型的列表。尽管大模型(LLM)也可以应用于聊天机器人,但专用的聊天模型(Chat Model)更适合对话场景。
  • 提示模板:帮助你整合默认消息、用户输入、历史交互以及检索时需要的上下文。
  • 记忆:它允许机器人记住与用户之间的先前互动,增强对话连贯性。
  • 检索器:这是一个可选组件,特别适合那些需要提供特定领域知识的机器人。

整体来说,聊天机器人的关键在于其记忆和检索能力,记忆使聊天机器人能够记住过去的交互,而检索则为聊天机器人提供最新的、特定于领域的信息。

项目的技术实现细节

在这个聊天机器人的实现过程中,我们将遵循敏捷开发的原则。先集中精力开发一个基础版本的机器人,实现最核心的功能,比如说能够聊天就可以了。然后,再逐步加入更多的功能,例如,能够基于易速鲜花的企业知识库进行检索,比如,用户可以输入订单号来查询订单状态,或询问如何退货等常见问题。

这个项目的具体技术实现步骤,这里简述一下。

第一步: 通过LangChain的ConversationChain,实现一个最基本的聊天对话工具。

第二步: 通过LangChain中的记忆功能,让这个聊天机器人能够记住用户之前所说的话。

第三步: 通过LangChain中的检索功能,整合易速鲜花的内部文档资料,让聊天机器人不仅能够基于自己的知识,还可以基于易速鲜花的业务流程,给出专业的回答。

第四步(可选): 通过LangChain中的数据库查询功能,让用户可以输入订单号来查询订单状态,或者看看有没有存货等等。

第五步: 在网络上部署及发布这个聊天机器人,供企业内部员工和易速鲜花用户使用。

在上面的 5 个步骤中,我们使用到了很多LangChain技术,包括提示工程、模型、链、代理、RAG、数据库检索等。

这节课我们先来实现项目的前三个步骤,第四个步骤我会留给你作为思考题,你可以复习并参考第17讲中的内容来实现它。在下节课中,我将为你介绍两个 AI 网络 UI 框架,Streamlit 和 Gradio,利用这两个框架,你可以轻松地把你的 AI 应用部署到网络中。

第一步:开发最基本的聊天机器人

让我们先来用LangChain打造出一个最简单的聊天机器人。

# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'# 导入所需的库和模块
from langchain.schema import (HumanMessage,SystemMessage
)
from langchain.chat_models import ChatOpenAI# 创建一个聊天模型的实例
chat = ChatOpenAI()# 创建一个消息列表
messages = [SystemMessage(content="你是一个花卉行家。"),HumanMessage(content="朋友喜欢淡雅的颜色,她的婚礼我选择什么花?")
]# 使用聊天模型获取响应
response = chat(messages)
print(response)

运行程序,输出如下:

content='对于喜欢淡雅的颜色的婚礼,你可以选择以下花卉:\n\n1. 白色玫瑰:白色玫瑰象征纯洁和爱情,它们能为婚礼带来一种优雅和浪漫的氛围。\n\n2. 紫色满天星:紫色满天星是十分优雅的小花,它们可以作为装饰花束或餐桌中心点使用,为婚礼增添一丝神秘感。\n\n3. 淡粉色康乃馨:淡粉色康乃馨是一种温馨而浪漫的花卉,能为婚礼带来一种柔和的氛围。\n\n4.  白色郁金香:白色郁金香代表纯洁和完美,它们可以为婚礼带来一种高贵和典雅的感觉。\n\n5. 淡紫色蓝雏菊:淡紫色蓝雏菊是一种可爱的小花,它们可以作为装饰花束或花冠使用,为婚礼增添一丝童真和浪漫。\n\n这些花卉都能营造出淡雅的氛围,并与婚礼的整体风格相得益彰。当然,你也可以根据你朋友的喜好和主题来选择适合的花卉。'

下面,我把它重构一下,让Chatbot能够和我们循环地进行对话。

# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'# 导入所需的库和模块
from langchain.schema import HumanMessage, SystemMessage
from langchain.chat_models import ChatOpenAI# 定义一个命令行聊天机器人的类
class CommandlineChatbot:# 在初始化时,设置花卉行家的角色并初始化聊天模型def __init__(self):self.chat = ChatOpenAI()self.messages = [SystemMessage(content="你是一个花卉行家。")]# 定义一个循环来持续与用户交互def chat_loop(self):print("Chatbot 已启动! 输入'exit'来退出程序。")while True:user_input = input("你: ")# 如果用户输入“exit”,则退出循环if user_input.lower() == 'exit':print("再见!")break# 将用户的输入添加到消息列表中,并获取机器人的响应self.messages.append(HumanMessage(content=user_input))response = self.chat(self.messages)print(f"Chatbot: {response.content}")# 如果直接运行这个脚本,启动聊天机器人
if __name__ == "__main__":bot = CommandlineChatbot()bot.chat_loop()

运行程序后,你可以一直和这个Bot聊天,直到你聊够了,输入exit,它会和你说再见。

好的,一个简单的聊天机器人已经搭建好了,不过,这个聊天机器人没有记忆功能,它不会记得你之前说过的话。

下面,我们要通过记忆机制,把它改造成一个能记住话的Chatbot。

第二步:增加记忆机制

下面,我们来通过ConversationBufferMemory给Chatbot增加记忆。具体代码如下:

# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'# 导入所需的库和模块
from langchain.schema import HumanMessage, SystemMessage
from langchain.memory import ConversationBufferMemory
from langchain.prompts import (ChatPromptTemplate,MessagesPlaceholder,SystemMessagePromptTemplate,HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI# 设置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'  # 带记忆的聊天机器人类
class ChatbotWithMemory:def __init__(self):# 初始化LLMself.llm = ChatOpenAI()# 初始化Promptself.prompt = ChatPromptTemplate(messages=[SystemMessagePromptTemplate.from_template("你是一个花卉行家。你通常的回答不超过30字。"),MessagesPlaceholder(variable_name="chat_history"),HumanMessagePromptTemplate.from_template("{question}")])# 初始化Memoryself.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)# 初始化LLMChain with LLM, prompt and memoryself.conversation = LLMChain(llm=self.llm,prompt=self.prompt,verbose=True,memory=self.memory)# 与机器人交互的函数def chat_loop(self):print("Chatbot 已启动! 输入'exit'来退出程序。")while True:user_input = input("你: ")if user_input.lower() == 'exit':print("再见!")breakresponse = self.conversation({"question": user_input})print(f"Chatbot: {response['text']}")if __name__ == "__main__":# 启动Chatbotbot = ChatbotWithMemory()bot.chat_loop()

程序的核心是ChatbotWithMemory类,这是一个带有记忆功能的聊天机器人类。在这个类的初始化函数中,定义了一个对话缓冲区记忆,它会跟踪对话历史。在LLMChain被创建时,就整合了LLM、提示和记忆,形成完整的对话链。

你看,我们的 Chatbot 成功地复述出了我好几轮之前传递给它的关键信息,也就是我的姐姐已经44岁了。她的推荐是基于这个原则来进行的。

第三步:增加检索机制

下面,继续增强 Chatbot 的功能,我们要把易速鲜花的内部文档信息嵌入到大模型的知识库中。让它成为一个拥有“易速鲜花”价值观的Super客服。

上图中的易速鲜花内部价值观,如果你感到陌生的话,可以复习一下易速鲜花的内容。

# 导入所需的库
import os
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Qdrant
from langchain.memory import ConversationSummaryMemory
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader# 设置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'  # ChatBot类的实现-带检索功能
class ChatbotWithRetrieval:def __init__(self, dir):# 加载Documentsbase_dir = dir # 文档的存放目录documents = []for file in os.listdir(base_dir): file_path = os.path.join(base_dir, file)if file.endswith('.pdf'):loader = PyPDFLoader(file_path)documents.extend(loader.load())elif file.endswith('.docx') or file.endswith('.doc'):loader = Docx2txtLoader(file_path)documents.extend(loader.load())elif file.endswith('.txt'):loader = TextLoader(file_path)documents.extend(loader.load())# 文本的分割text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0)all_splits = text_splitter.split_documents(documents)# 向量数据库self.vectorstore = Qdrant.from_documents(documents=all_splits, # 以分块的文档embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入location=":memory:",  # in-memory 存储collection_name="my_documents",) # 指定collection_name# 初始化LLMself.llm = ChatOpenAI()# 初始化Memoryself.memory = ConversationSummaryMemory(llm=self.llm, memory_key="chat_history", return_messages=True)# 设置Retrieval Chainretriever = self.vectorstore.as_retriever()self.qa = ConversationalRetrievalChain.from_llm(self.llm, retriever=retriever, memory=self.memory)# 交互对话的函数def chat_loop(self):print("Chatbot 已启动! 输入'exit'来退出程序。")while True:user_input = input("你: ")if user_input.lower() == 'exit':print("再见!")break# 调用 Retrieval Chain  response = self.qa(user_input)print(f"Chatbot: {response['answer']}")if __name__ == "__main__":# 启动Chatbotfolder = "OneFlower"bot = ChatbotWithRetrieval(folder)bot.chat_loop()

通过文档加载、文本分割、文档向量化以及检索功能,这个新的机器人除了常规的聊天功能,还能够检索存储在指定目录中的文档,并基于这些文档提供答案。

当用户输入一个问题时,机器人首先在向量数据库中查找与问题最相关的文本块。这是通过将用户问题转化为向量,并在数据库中查找最接近的文本块向量来实现的。然后,机器人使用 LLM(大模型)在这些相关的文本块上进一步寻找答案,并生成回答。

现在,新的Chatbot既能够回答一般性的问题,又能够回答易速鲜花内部问题,成了一个多面手!

总结

咱们的聊天机器人基本完成。它拥有了很多能力,有些能力来自于模型本身,比如World Knowledge(世界知识)、总结、对话等等。除此之外,我们还为它武装了记忆功能以及检索易速鲜花内部文档的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/62289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT/AI辅助网络安全运营之-数据解压缩

在网络安全的世界中,经常会遇到各种压缩的数据,比如zip压缩,比如bzip2压缩,gzip压缩,xz压缩,7z压缩等。网络安全运营中需要对这些不同的压缩数据进行解压缩,解读其本意,本文将探索一…

05_JavaScript注释与常见输出方式

JavaScript注释与常见输出方式 JavaScript注释 源码中注释是不被引擎所解释的,它的作用是对代码进行解释。lavascript 提供两种注释的写法:一种是单行注释,用//起头:另一种是多行注释,放在/*和*/之间。 //这是单行注释/* 这是 多行 注释 *…

网络原理(一):应用层自定义协议的信息组织格式 HTTP 前置知识

目录 1. 应用层 2. 自定义协议 2.1 根据需求 > 明确传输信息 2.2 约定好信息组织的格式 2.2.1 行文本 2.2.2 xml 2.2.3 json 2.2.4 protobuf 3. HTTP 协议 3.1 特点 4. 抓包工具 1. 应用层 在前面的博客中, 我们了解了 TCP/IP 五层协议模型: 应用层传输层网络层…

题目 3209: 蓝桥杯2024年第十五届省赛真题-好数

一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 )上的数字是奇数,偶数位(十位、千位、十万位 )上的数字是偶数,我们就称之为“好数”。给定一个正整数 N,请计算从…

数据结构与算法学习笔记----KMP

数据结构与算法学习笔记----KMP author: 明月清了个风 last edited: 2024.11.24 Acwing 831. KMP字符串 给定一个字符串 S S S,以及一个模式串 P P P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模式串 P P P在字符串 S S S中多次作为子串出…

算法基础 - 二分迭代法求解非线性方程

文章目录 1. 基本思想2. 编程实现2.1. 非递归2.2. 递归方案 3. 总结 二分迭代法使用了二分算法思想求解非线性方程式。 下面要求使用二分迭代法求解: 2x3-5x-10 方程式,且要求误差不能大于10e-5。 二分迭代法也只是近似求解算法。 所谓求解&#xff…

家校通小程序实战教程03学生管理

目录 1 创建数据源2 搭建后台功能3 设置主列字段4 批量导入数据5 设置查询条件6 实现查询和重置总结 我们现在已经搭建了班级管理,并且录入了班级口令。之后就是加入班级的功能了。这里分为老师加入班级和学生家长加入班级。 如果是学生家长的话,在加入之…

springboot336社区物资交易互助平台pf(论文+源码)_kaic

毕 业 设 计(论 文) 社区物资交易互助平台设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此&#xff…

【C++】7000字介绍map容器和set容器的功能和使用

目录 一、关联式容器和序列式容器 二、键值对,> 三、树形结构的关联式容器 四、set容器(key模型) 1、文档官网 2、功能介绍: 3、注意事项: 4、基本使用,更多接口可查看官网: (1&…

嵌入式C语言技巧15:深入浅出:多线程编程中锁的选择与优化策略

文章目录 导读一、锁机制概览二、实战演练:锁的选择与使用三、代码执行结果与分析四、总结与展望本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观…

【Git】常用命令汇总

目录 一.安装及配置 1.在 Windows 上安装 2.用户信息 3.差异分析工具 二.基础 1.创建仓库 2.提交与修改 三.分支管理 1.创建分支 2.合并分支 四.远程操作 1.管理 Git 仓库中的远程仓库 2.数据的获取与推送 五.标签 1.创建轻量标签和附注标签 2.查看标签和标签信…

AWS海外注册域名是否需要实名认证?

在全球化的互联网环境中,注册域名已成为企业和个人建立在线存在的重要步骤。亚马逊网络服务(AWS)作为全球领先的云服务提供商,其域名注册服务也备受关注。然而,对于在AWS上注册海外域名是否需要实名认证,许…

【C++进阶篇】像传承家族宝藏一样理解C++继承

文章目录 须知 💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力! 👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗&#xff1…

DAMODEL丹摩|部署FLUX.1+ComfyUI实战教程

本文仅做测评体验,非广告。 文章目录 1. FLUX.1简介2. 实战2. 1 创建资源2. 1 ComfyUI的部署操作2. 3 部署FLUX.1 3. 测试5. 释放资源4. 结语 1. FLUX.1简介 FLUX.1是由黑森林实验室(Black Forest Labs)开发的开源AI图像生成模型。它拥有12…

具体的技术和工具在县级融媒体建设3.0中有哪些应用?

以下是结合数据来看县级融媒体建设3.0的一些情况: 技术应用方面 大数据:人民网舆情数据中心执行主任董盟君提到,通过大数据分析可让融媒体单位快速关注聚焦点,实现智能策划、智能推送、智能传播,推动媒体传播影响力提…

中兴机顶盒B860AV1.1刷机固件升级和教程「适用4/8G版」

准备工作: TTL 线(CH340G 按系统版本找到要对应驱动)下载 putty 软件拆开电视盒接好 TTL 线(2、5、6 针脚对应GND、RX、TX)在资源管理器的端口选项下找到 CH340G,记住端口号(如 COM4&#xff0…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发,开发自己的软件,例如:【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等,不管是您用来个人学习 还是公司研发需求,都相当合适,包您满…

QINQ技术

定义 QINQ即802.1q in 802.1q,因为IEEE802.1Q中定义的Vlan Tag域只有12个比特,仅能表示4096个Vlan,随网络发展被用尽,于是在原有带vlan的数据上再携带一层vlan标签用于扩展vlan数目。一般来说外层vlan是公网,内层是私…

linux基础2

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…

鸿蒙千帆启新程,共绘数字生态蓝图

华为的鸿蒙千帆起计划:共筑数字未来,学习华为创新之路 在当今全球科技竞争日益激烈的背景下,华为作为中国科技企业的代表,正通过其自主创新的鸿蒙系统,引领一场移动应用生态的变革。鸿蒙千帆起计划,作为华…