LangChain实战课之易速鲜花聊天客服机器人的开发 | 豆包MarsCode AI刷题

170 阅读6分钟

一、项目概述

  1. 项目背景与目标

    • 为易速鲜花市场部、销售部、客服部门员工及广大用户开发聊天机器人。
    • 聊天机器人应具备长时间对话、理解用户意图、访问相关信息的能力,其核心组件包括聊天模型、提示模板、记忆和检索器(可选),关键在于记忆和检索能力。
  2. 技术实现步骤

    • 第一步:通过 LangChain 的 ConversationChain 实现基本聊天对话工具。
    • 代码示例:
# 设置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)
  • 第二步:利用 LangChain 的记忆功能让聊天机器人记住用户之前的话。

  • 代码示例:

# 设置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):
        # 初始化LLM
        self.llm = ChatOpenAI()
        # 初始化Prompt
        self.prompt = ChatPromptTemplate(
            messages=[
                SystemMessagePromptTemplate.from_template(
                    "你是一个花卉行家。你通常的回答不超过30字。"
                ),
                MessagesPlaceholder(variable_name="chat_history"),
                HumanMessagePromptTemplate.from_template("{question}")
            ]
        )
        
        # 初始化Memory
        self.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
        
        # 初始化LLMChain with LLM, prompt and memory
        self.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("再见!")
                break
            
            response = self.conversation({"question": user_input})
            print(f"Chatbot: {response['text']}")
if __name__ == "__main__":
    # 启动Chatbot
    bot = ChatbotWithMemory()
    bot.chat_loop()
  • 第三步:运用 LangChain 的检索功能整合易速鲜花内部文档资料,使机器人能基于业务流程给出专业回答。
  • 代码示例:
# 导入所需的库
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):
        # 加载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']}")
if __name__ == "__main__":
    # 启动Chatbot
    folder = "OneFlower"
    bot = ChatbotWithRetrieval(folder)
    bot.chat_loop()
  • 第四步:通过 LangChain 的数据库查询功能让用户可查询订单状态等信息。
  • 第五步:在网络上部署及发布聊天机器人。

二、新知识学习与理解

  1. LangChain 技术应用

    • 提示工程:在构建聊天机器人时,通过精心设计提示模板,如在增加记忆机制的代码中,使用 ChatPromptTemplate 来组织系统消息、聊天历史占位符和用户问题模板,引导模型生成更符合预期的回答。合理的提示工程有助于提高模型对任务的理解和执行能力。
    • 模型选择:选用 ChatOpenAI 作为聊天模型,它更适合对话场景,能生成自然的对话风格的回复。不同的模型在不同的应用场景下有不同的优势,选择合适的模型是构建有效聊天机器人的重要环节。
    • 链的运用:LLMChain 将语言模型、提示模板和记忆等组件整合在一起,形成一个完整的对话链。在带记忆功能的聊天机器人代码中,通过 LLMChain 实现了与模型的交互,并结合记忆功能提供连贯的对话体验。ConversationalRetrievalChain 则在检索功能中发挥作用,将模型与向量数据库检索相结合,使机器人能在知识库中查找信息并回答问题。
    • 代理(未在本次代码中详细体现,但在整体技术中提及) :代理可以帮助聊天机器人决定采取何种行动,例如在复杂任务中决定是直接回答问题还是调用其他工具或服务。这为构建更智能、功能更强大的聊天机器人提供了可能性。
    • RAG(检索增强生成) :通过文档加载、文本分割、向量化等步骤将易速鲜花内部文档信息嵌入大模型知识库,实现了检索增强生成。当用户提问时,机器人先在向量数据库中检索相关文本块,再利用大模型在这些文本块上生成答案。这使得机器人不仅能依靠自身知识,还能基于特定领域的文档提供准确和专业的回答。
  2. 记忆与检索功能实现

    • 记忆功能:使用 ConversationBufferMemory 实现记忆机制,它跟踪对话历史,在后续对话中可以利用之前的交互信息。例如,机器人能记住用户之前提到的相关内容,从而提供更有针对性和连贯性的回答。这对于需要进行多轮对话的场景非常重要,增强了用户体验。
    • 检索功能:借助 RecursiveCharacterTextSplitter 将文档分割成合适的块,利用 OpenAIEmbeddings 将文本向量化,存储在 Qdrant 向量数据库中。通过设置检索器,机器人能够在向量数据库中快速查找与用户问题相关的文本块,然后基于这些文本块和大模型生成回答。这使得机器人能够获取最新的、特定于易速鲜花业务领域的信息,扩大了其知识范围,提高了回答的专业性和准确性。

三、思考与总结

  1. 代码重构与优化

    • 思考题中提到可以用 ConversationChain 中的 Memory 来重构代码,这提示我们在实际开发中可以不断探索更简洁、高效的代码实现方式。根据提示,ConversationChain 对 Memory 和 LLMChain 进行了封装,简化了初始化 Memory 的步骤,我们可以深入研究其原理,尝试在现有代码基础上进行改进,提高代码的可读性和可维护性。
  2. 功能扩展

    • 对于增加数据库查询功能的思考题,这是对聊天机器人功能的进一步拓展。如果实现了该功能,聊天机器人将能更好地服务于业务需求,如查询鲜花库存、销售情况等。
  3. 实际应用与价值

    • 本聊天机器人项目为易速鲜花相关人员提供了一个实用的工具。在实际应用中,它可以提高客户服务效率,帮助市场部和销售部更好地了解产品信息和业务流程,从而提升工作效率和客户满意度。同时,通过不断优化和扩展功能,聊天机器人可以成为企业数字化转型中的重要组成部分,为企业提供更多的价值,如数据分析(通过记录和分析用户对话)、智能推荐(根据用户需求和历史记录推荐鲜花产品或服务)等。