易速鲜花聊天客服机器人的开发(下) | 豆包MarsCode AI刷题

96 阅读5分钟

文档总结

上期我简单总结了,一个易速鲜花聊天客服机器人的开发流程。不过那只是上的内容,这期我将总结下的内容,如何把它部署到网络上。这个聊天机器人项目通过LangChain的ConversationChain实现,具备记忆功能,能够记住用户之前的对话,并整合了易速鲜花的内部文档资料,提供专业的回答。此外,还介绍了如何使用Streamlit和Gradio这两个框架来部署聊天机器人。

项目设计回顾:

  1. 基础聊天对话工具:通过LangChain的ConversationChain实现。
  2. 记忆功能:使聊天机器人能够记住用户之前所说的话。
  3. 检索功能:整合易速鲜花的内部文档资料,提供基于业务流程的专业回答。
  4. 数据库查询功能(可选):允许用户查询订单状态或存货等。
  5. 网络部署:发布聊天机器人供企业内部员工和用户使用。

部署框架选择:

  • Flask:一个通用的、微型的Web应用框架,适合创建各种Web应用程序,提供高灵活性,但可能需要更多时间学习,尤其是结合前端技术和数据库技术时。
  • Streamlit:一个为数据科学家和机器学习工程师设计的开源Python库,能够迅速将Python脚本转化为交互式Web应用。它的特点包括简易性、无需前端经验、实时交互、内置组件、数据集可视化、设计简洁、部署和共享。 由于您提供的文档内容中包含了两部分代码,一部分是使用Streamlit部署聊天机器人的代码,另一部分是使用Gradio部署聊天机器人的代码,我将这两部分代码一起附上。

Streamlit部署: 通过Streamlit,我们可以快速创建一个网页版的聊天机器人。首先,安装Streamlit,然后通过几行代码创建一个简单的Web应用。Streamlit的应用可以通过streamlit run命令运行,并在浏览器中查看。在Streamlit中,我们使用会话状态来存储用户会话,并创建文本输入框供用户输入问题。聊天机器人的响应会显示在应用程序界面上。

使用Streamlit部署聊天机器人的代码:

import os
import streamlit as st
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):
        # 加载Documents
        base_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
        
        # 初始化LLM
        self.llm = ChatOpenAI()
        
        # 初始化Memory
        self.memory = ConversationSummaryMemory(
            llm=self.llm, 
            memory_key="chat_history", 
            return_messages=True
            )
        
        # 设置Retrieval Chain
        retriever = 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']}")

# Streamlit界面的创建
def main():
    st.title("易速鲜花聊天客服")

    # Check if the 'bot' attribute exists in the session state
    if "bot" not in st.session_state:
        st.session_state.bot = ChatbotWithRetrieval("OneFlower")

    user_input = st.text_input("请输入你的问题:")
    
    if user_input:
        response = st.session_state.bot.qa(user_input)
        st.write(f"Chatbot: {response['answer']}")

if __name__ == "__main__":
    main()
  • Gradio:一个界面更侧重于模型交互的框架,上手简单,适合展示和测试机器学习模型。

Gradio部署: Gradio提供了一种快速的方法,使非技术用户也能与机器学习模型进行交互。通过Gradio,我们可以定义一个界面,其中包含一个文本输入和一个文本输出。用户可以输入问题并提交,然后聊天机器人会返回响应。Gradio界面的启动会打开一个新窗口,用户可以通过这个界面与机器人交互。

使用Gradio部署聊天机器人的代码:

import os
import gradio as gr
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'  

class ChatbotWithRetrieval:
    def __init__(self, dir):
        # 加载Documents
        base_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
        
        # 初始化LLM
        self.llm = ChatOpenAI()
        
        # 初始化Memory
        self.memory = ConversationSummaryMemory(
            llm=self.llm, 
            memory_key="chat_history", 
            return_messages=True
            )
        # 初始化对话历史
        self.conversation_history = ""

        # 设置Retrieval Chain
        retriever = self.vectorstore.as_retriever()
        self.qa = ConversationalRetrievalChain.from_llm(
            self.llm, 
            retriever=retriever, 
            memory=self.memory
            )

    def get_response(self, user_input):  # 这是为 Gradio 创建的新函数
        response = self.qa(user_input)
        # 更新对话历史
        self.conversation_history += f"你: {user_input}\nChatbot: {response['answer']}\n"
        return self.conversation_history

if __name__ == "__main__":
    folder = "OneFlower"
    bot = ChatbotWithRetrieval(folder)

    # 定义 Gradio 界面
    interface = gr.Interface(
        fn=bot.get_response,  # 使用我们刚刚创建的函数
        inputs="text",  # 输入是文本
        outputs="text",  # 输出也是文本
        live=False,  # 实时更新,这样用户可以连续与模型交互
        title="易速鲜花智能客服",  # 界面标题
        description="请输入问题,然后点击提交。"  # 描述
    )
    interface.launch()  # 启动 Gradio 界面

总结时刻: 我对Streamlit的理解是,它极大地简化了数据科学项目的Web部署过程。通过Streamlit,我可以快速创建一个交互式的Web应用,而无需深入了解前端开发。Streamlit的实时交互功能也使得迭代和实验变得更加便捷。

Gradio则让我看到了如何快速构建一个用户友好的界面,使得非技术用户也能轻松地与机器学习模型进行交互。Gradio的简单性和易用性使其成为展示和测试模型的理想选择。