LangChain构建智能文档问答系统 | 豆包MarsCode AI刷题

105 阅读3分钟

项目概述

本文记录了如何使用LangChain框架构建一个企业内部知识库问答系统的实践过程。项目以"易速鲜花"公司为例,实现了一个能够智能回答员工关于公司政策、流程等问题的系统。

系统架构

整个系统分为三大模块:

  1. 数据源(Data Sources):处理PDF、Word、TXT等非结构化数据
  2. LLM应用(LLM App):使用大语言模型作为处理核心
  3. 应用场景(Use-Cases):实现智能问答功能

核心实现步骤

1. 文档加载

使用LangChain的document_loaders加载不同格式的文档:

python
Copy
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())

代码解析:

  • 使用不同的loader处理不同格式文件
  • extend()方法将加载的文档添加到统一的documents列表
  • 通过文件扩展名判断使用哪种loader

2. 文本分割

使用RecursiveCharacterTextSplitter进行文本切分:

python
Copy
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,  # 每个文本块的大小
    chunk_overlap=10  # 相邻块的重叠部分
)
chunked_documents = text_splitter.split_documents(documents)

代码解析:

  • chunk_size=200:将文档分割成200字符的块
  • chunk_overlap=10:设置10字符的重叠,确保上下文的连贯性
  • 分割后的文档块便于后续向量化和存储

3. 向量存储

使用OpenAI Embeddings生成文本向量,并存储到Qdrant向量数据库:

python
Copy
from langchain.vectorstores import Qdrant
from langchain.embeddings import OpenAIEmbeddings

vectorstore = Qdrant.from_documents(
    documents=chunked_documents,  # 分块后的文档
    embedding=OpenAIEmbeddings(),  # OpenAI的Embedding模型
    location=":memory:",  # 内存存储
    collection_name="my_documents"  # 集合名称
)

代码解析:

  • 使用OpenAI的Embedding模型将文本转换为向量
  • 选择Qdrant作为向量数据库,支持高效的相似度检索
  • :memory:表示数据存储在内存中,也可以配置持久化存储

4. 检索问答链配置

设置检索式问答模型:

python
Copy
from langchain.chat_models import ChatOpenAI
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain.chains import RetrievalQA

# 配置GPT模型
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
)

代码解析:

  • temperature=0:确保输出的一致性
  • MultiQueryRetriever能够优化检索效果
  • RetrievalQA链将检索和问答过程串联起来

5. Web接口实现

使用Flask构建简单的Web界面:

python
Copy
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)

代码解析:

  • 支持GET和POST请求
  • POST请求处理用户提交的问题
  • 调用qa_chain生成答案并返回

技术要点总结

  1. 模块化设计

    • 各个组件职责明确
    • 便于维护和扩展
  2. 文档处理

    • 支持多种格式
    • 智能分块策略
    • 向量化存储
  3. 检索优化

    • 使用向量数据库
    • MultiQueryRetriever提升检索质量
    • 余弦相似度匹配
  4. 问答生成

    • 基于GPT-3.5模型
    • 结合本地知识库
    • 实时响应

优化建议

  1. 考虑使用其他向量数据库如Chroma进行对比测试
  2. 可以尝试使用不同的开源模型替代GPT-3.5
  3. 增加文档更新机制,确保知识库及时更新
  4. 添加用户反馈机制,持续优化回答质量