青训营X豆包MarsCode 技术训练营第三课 | 豆包MarsCode AI 刷题

130 阅读4分钟

易速鲜花内部员工知识库问答系统项目笔记

项目背景与需求分析

"易速鲜花"是一家大型在线鲜花销售平台,为提高员工培训效率、优化信息查询方式,计划开发一个内部员工知识库问答系统。该系统旨在帮助新员工快速查询公司政策、业务流程及最新信息。传统方式下,员工获取信息主要依赖内部网络和HR部门手册,但由于文档分散、冗长、更新不及时等原因,员工往往难以快速获取所需信息。因此,本项目计划开发一个基于文档问答(Doc-QA)的系统,整合公司内部的SOP手册,并能快速提供精准答案。

实现框架

项目主要采用LangChain框架,LangChain能够通过不同的模块实现基于文档的问答系统,适合处理多种数据源。项目整体框架如下:

  1. 数据源(Data Sources):包括PDF、Word和TXT等非结构化数据。
  2. 大模型应用(Application):依赖语言模型(LLM)理解员工问题,生成答案。
  3. 用例(Use-Cases):基于大模型的回答构建员工问答系统。

核心实现机制与流程

项目实现主要基于以下五步:

  1. Loading(加载文档): 利用LangChain中的document_loaders加载PDF、Word和TXT文件,并将文本存储在一个列表中。示例代码如下:

    import os
    os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'
    
    # 导入Document Loaders
    from langchain.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader
    
    base_dir = './OneFlower'  # 文档目录
    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'):
            loader = Docx2txtLoader(file_path)
            documents.extend(loader.load())
        elif file.endswith('.txt'):
            loader = TextLoader(file_path)
            documents.extend(loader.load())
    
  2. Splitting(文本分割): 为便于后续嵌入和存储,将文档分割成更小的文本块。使用RecursiveCharacterTextSplitter将文档分割成200字符左右的块,示例代码如下:

    from langchain.text_splitter import RecursiveCharacterTextSplitter
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
    chunked_documents = text_splitter.split_documents(documents)
    
  3. Storage(向量存储): 将文本块转换为向量形式并存储于向量数据库中。向量数据库可以存储文本块的嵌入数据(向量化后的数据),在项目中使用Qdrant数据库。向量数据库支持语义搜索,可以高效检索相似内容。示例代码如下:

    from langchain.vectorstores import Qdrant
    from langchain.embeddings import OpenAIEmbeddings
    vectorstore = Qdrant.from_documents(
        documents=chunked_documents,
        embedding=OpenAIEmbeddings(),
        location=":memory:",
        collection_name="my_documents",
    )
    
  4. Retrieval(检索): 利用检索器根据用户问题从向量数据库中找到相关的文档块,通过余弦相似度计算找到最相关的嵌入。采用MultiQueryRetriever实现多查询检索,提高检索的准确性。示例代码如下:

    from langchain.chat_models import ChatOpenAI
    from langchain.retrievers.multi_query import MultiQueryRetriever
    from langchain.chains import RetrievalQA
    
    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
    retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)
    qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever_from_llm)
    
  5. Output(输出生成答案): 使用Flask创建Web界面接收用户问题,将问题传递至RetrievalQA链,并展示生成的答案。示例代码如下:

    from flask import Flask, request, render_template
    app = Flask(__name__)
    
    @app.route('/', methods=['GET', 'POST'])
    def home():
        if request.method == 'POST':
            question = request.form.get('question')
            result = qa_chain({"query": question})
            return render_template('index.html', result=result)
        return render_template('index.html')
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', debug=True, port=5000)
    

技术要点

  1. 词嵌入:将文本转为向量,用于保留语义信息。相似词在向量空间中距离较近,使得模型可以基于语义相似度提供答案。
  2. 向量数据库:用于存储和检索高维向量。向量数据库支持高效的相似度计算(如余弦相似度),非常适合文本数据的语义搜索需求。
  3. 检索式问答:结合LLM与向量数据库的检索功能,通过问题与文档块的相似度计算,实现基于内部知识的精准回答。

可能的扩展

  1. Chroma数据库:LangChain支持多种向量数据库,Chroma是一种较常用的开源向量数据库,可以替代Qdrant实现文档块的存储。
  2. HuggingFace开源模型:除了OpenAI的模型,还可尝试使用HuggingFace的google/flan-t5-x1等开源模型替代GPT-3.5以降低成本。

总结

通过LangChain框架和大模型,本项目构建了一个“易速鲜花”内部知识库问答系统。系统采用五步流程,包括文档加载、分割、存储、检索和输出。利用大模型与向量数据库的结合,系统能够快速检索相关内容,并以语义理解为基础生成精准答案。