LangChain项目框架
整体框架
整个框架分为这样三个部分:
- 数据源(Data Sources)
- 大模型应用(Application,即LLM App
- 用例(Use-Cases)
框架组成部分
| 组成部分 | 描述 |
|---|---|
| 数据源 (Data Sources) | 包含非结构化数据(如PDF、Word、TXT文件)和结构化数据(如SQL),可高效加载和解析多种文档格式。 |
| 大模型应用 (Application) | 利用大模型(LLM)作为逻辑引擎,生成针对用户问题的回答,使用户能够快速得到所需信息。 |
| 用例 (Use Cases) | 基于大模型生成的回答构建的QA系统或聊天机器人,实际应用于日常工作中,提高整体工作效率。 |
核心实现机制
项目的核心实现机制是下图所示的数据处理管道:
Loading -> Splitting -> Storage -> Retrieval -> Output
各环节详细解析
-
Loading(加载):
- 功能描述:加载各种格式的文档(PDF、Word、TXT)并将其存储在列表中。通过LangChain的document loaders实现这一过程。
- 代码示例:
import os from langchain.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader base_dir = './documents' # 文件存放目录 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())
-
Splitting(分割):
- 功能描述:将加载的文档分割为较小的块,以便进行嵌入和向量存储。使用LangChain中的
RecursiveCharacterTextSplitter进行文本分割。 - 代码示例:
from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10) chunked_documents = text_splitter.split_documents(documents)
- 功能描述:将加载的文档分割为较小的块,以便进行嵌入和向量存储。使用LangChain中的
-
Storage(存储):
- 功能描述:将分割后的文档块转换为嵌入形式并存储在向量数据库中。使用OpenAI的Embedding模型生成嵌入,并存储在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" )
-
Retrieval(检索):
- 功能描述:根据用户问题检索相关的文档块,使用大模型生成答案。检索过程基于输入问题的向量与数据库中向量的相似度比较,通常使用余弦相似度。
- 代码示例:
from langchain.chains import RetrievalQA qa_chain = RetrievalQA.from_chain_type(llm, retriever=vectorstore.as_retriever())
-
Output(输出):
- 功能描述:创建用户界面与用户互动,展示生成的答案。使用Flask框架提供用户友好的界面。
- 代码示例:
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)
概念补充解释
| 概念 | 定义 |
|---|---|
| 词嵌入(Word Embedding) | 将文字或词语转换为数字向量,保留词汇的语义关系。 |
| 向量数据库 | 用于存储和搜索高维向量数据,提升处理非结构化数据的效率。与传统关系型数据库不同,向量数据库专门设计用于处理高维向量数据,优化查询性能。 |
向量之间的比较及选择标准
| 方法 | 描述 | 适用场景 |
|---|---|---|
| 欧氏距离 | 测量两个向量之间的绝对距离,适合用于评估向量的大小差异。 | 数据量较小的物品推荐系统,关注用户偏好的绝对强度。 |
| 余弦相似度 | 测量两个向量之间的方向相似性,更加关注向量的角度差异,适合用于文本数据处理。 | 信息检索、文本分类等,关注文本的语义相似性。 |
选择标准
| 选择标准 | 描述 |
|---|---|
| 使用欧氏距离 | 在关注数量等大小差异的场景,例如物品推荐系统,用户的购买量反映其偏好强度时使用。 |
| 使用余弦相似度 | 在关注文本等语义差异的场景,如处理文本数据时,选择余弦相似度能更好地捕捉语义相似性。 |
总结与反思
通过使用LangChain框架和大模型,可以高效构建内部知识问答系统,简化信息获取和处理流程。该框架展示了如何将复杂的自然语言处理任务转化为可操作的流程,有效提升用户在获取知识时的效率。
整体流程:
加载文档 -> 切分文档 -> 存储嵌入 -> 检索相关信息 -> 生成答案 -> 显示答案