学习笔记:基于LangChain的“易速鲜花”内部员工知识库问答系统实现 | 豆包MarsCode AI刷题
项目背景
“易速鲜花”作为一个大型在线鲜花销售平台,拥有大量的员工手册和规范文档。由于这些文档内容分散且不断更新,员工在查找信息时可能遇到困难。因此,我们决定开发一个基于LangChain框架的智能问答系统,帮助员工快速获取最新的公司政策和操作流程。
项目架构
这个项目分为以下几个部分:
- 数据源(Data Sources) :我们处理的主要是PDF、Word和TXT格式的文档,这些文档中包含了公司的业务规范和SOP手册。
- 大模型应用(LLM App) :大语言模型(如GPT-3.5)将作为问答引擎,基于用户提问生成答案。
- 用例(Use-Cases) :基于上述模型和数据源,我们构建一个文档问答系统,员工可以通过输入问题来获取答案。
实现流程
1. 数据加载
首先,我们使用LangChain的 document_loaders 来加载各种格式的文档。代码如下:
import os
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. 文本分割
为了高效处理这些文档,我们将它们分割成小块。这一过程是通过LangChain中的 RecursiveCharacterTextSplitter 实现的:
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
chunked_documents = text_splitter.split_documents(documents)
每个文档被分割成大约200字符的小块,以便于后续处理。
3. 向量数据库存储
接下来,我们将这些文档块转换为嵌入(Embedding),并存储在向量数据库中。这一过程利用了OpenAI的嵌入模型以及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. 信息检索与问答
为了实现信息的自动提取,我们创建了一个 RetrievalQA 链,它将用户的提问与向量数据库中最相关的文档块进行匹配,并返回答案:
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)
在此步骤中,RetrievalQA 链负责接收用户的问题,通过检索数据库中的相关文档并调用大模型生成答案。
5. 输出与用户交互
最后,我们使用Flask框架搭建了一个简单的Web界面,员工可以通过网页输入问题,系统返回基于文档的答案:
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)
HTML结构示例:
<form method="POST">
<label for="question">Enter your question:</label><br>
<input type="text" id="question" name="question"><br>
<input type="submit" value="Submit">
</form>
{% if result is defined %}
<h2>Answer</h2>
<p>{{ result.result }}</p>
{% endif %}
总结
整个项目流程包括文档加载、分割、存储、检索和答案生成,最终通过Flask展示给用户。通过LangChain框架,我们能够高效处理和查询公司内部文档,从而实现一个强大的问答系统,帮助员工快速查找所需信息。