LangChain实战课笔记02 基于本地知识库的问答系统开发 | 豆包MarsCode AI刷题

40 阅读5分钟

一、项目背景与目标

(一)项目背景

“易速鲜花” 作为大型在线鲜花销售平台,拥有自身业务流程、规范及员工 SOP 手册。新员工入职培训时虽会分享相关信息,但存在诸多问题。信息分散于内部网和 HR 部门目录各处,导致查询不便;文档冗长致使员工难以迅速定位所需内容;公司政策更新后,员工手头文档可能仍为旧版。

(二)项目目标

开发基于各种内部知识手册的 “Doc - QA” 系统,充分利用 LangChain 框架处理员工手册相关问题,使系统能理解员工问题并基于最新手册给出精准答案。

二、开发框架

(一)整体架构

  1. 数据源(Data Sources)

    • 数据类型多样,包括非结构化数据(如 PDF 等)、结构化数据(如 SQL 等)以及代码(如 Python、Java 等)。本项目着重处理非结构化数据,这些数据是构建知识库的基础材料。
  2. 大模型应用(Application,即 LLM App)

    • 大模型作为核心逻辑引擎,承担着生成准确回答的关键任务。它凭借强大的语言理解和生成能力,为整个问答系统提供智能支持。
  3. 用例(Use - Cases)

    • 基于大模型生成的回答,可以构建如 QA(问答系统)、聊天机器人等多种实用系统,拓展了系统的应用场景和价值。

(二)各部分关系

数据源为系统提供数据,大模型应用对数据进行处理和分析以生成回答,用例则是将回答应用于实际场景中,三者相互协作,共同构成完整的开发框架。

三、核心实现机制 - 数据处理管道(Pipeline)

(一)Loading(文档加载)

  1. 操作过程

    • 利用 LangChain 中的多种 document_loaders(如 PyPDFLoader 用于加载 PDF 文件、Docx2txtLoader 用于加载 Word 文件、TextLoader 用于加载 Txt 文件),从指定目录(如本项目中的 OneFlower 目录)加载不同格式的文本文件。将加载的文本存储在一个列表中,以便后续统一处理。
  2. 关键要点

    • 需导入 OpenAI API Key,原因是后续要使用 OpenAI 的 Embedding 模型为文档做嵌入以及调用 GPT 模型生成问答系统的回答。同时,要留意工具包的安装,若程序报错缺少某个包,可通过 pip install 命令安装相关包。例如,加载 PDF 文件可能需要安装 PyPDF 工具包,加载 Word 文件可能需要安装 Docx2txt 工具包。

(二)Splitting(文本分割)

  1. 操作过程

    • 使用 LangChain 中的 RecursiveCharacterTextSplitter,设置 chunk_size(块大小)为 200,chunk_overlap(块重叠)为 10,将加载的文档切分为指定大小的 “文档块” 或 “文档片”。
  2. 目的与意义

    • 分割后的文档块便于后续进行嵌入和向量存储操作,使得文档在进入向量数据库时能够以更合适的粒度进行处理,提高系统的准确性和效率。

(三)Storage(向量数据库存储)

  1. 操作过程

    • 运用 OpenAIEmbeddings 生成嵌入,将分割好的 “文档块” 以 “嵌入” 形式存储到 Qdrant 向量数据库中(需先安装 qdrant - client)。在存储过程中,指定 collection_name(如 “my_documents”)以便管理和检索。
  2. 概念解释与重要性

    • 词嵌入是将文字或词语转换为数字向量的技术,其数字并非随机,而是捕获了词的含义和上下文关系,语义相似的词在数字空间中接近。向量数据库专门用于存储和搜索向量数据,能高效处理高维向量数据,解决传统数据库在处理非结构化数据(如文本)时的效率问题,为后续的信息检索和问答提供有力支持。

(四)Retrieval(相关信息获取)

  1. 操作过程

    • 将问题转换为向量,与向量数据库中的向量进行比较。常用的比较方法有欧氏距离和余弦相似度,本项目处理文本数据且注重语义理解,选择余弦相似度作为度量标准。通过比较找到与问题最接近的 “嵌入片”,对应的 “文档块” 将作为知识信息传递给大模型。
  2. 方法选择依据

    • 欧氏距离度量绝对距离,适用于关心数量等大小差异的场景,如物品推荐系统中考虑用户购买量反映偏好强度时;余弦相似度度量方向相似性,更关注向量角度差异,适用于处理文本等语义差异场景,如信息检索和文本分类任务中。在本问答系统中,从语义上理解和比较问题答案,余弦相似度更能满足需求。

(五)Output(生成回答并展示)

  1. 操作过程

    • 创建 Flask 应用(需安装 Flask 包),通过 @app.route ('/') 设置路由,接收用户在网页上输入的问题。利用之前创建的 RetrievalQA 链,将问题传入获取相关文档并生成答案。最后通过 render_template ('index.html', result = result) 将答案返回给网页进行渲染呈现。
  2. 网页交互实现

    • 相关 HTML 网页包含标题、鲜花 logo、输入问题的表单(包含输入框和提交按钮)以及用于展示答案的区域(通过 Jinja2 模板语法判断 result 是否定义,若定义则展示答案)。用户在网页输入问题后,点击提交,系统生成答案并显示在网页上,实现了良好的 UI 交互。

四、总结

(一)项目流程总结

整个项目先将本地知识文档进行加载、分割、嵌入并存储到向量数据库,在接收到用户问题后,将问题转换为向量与数据库中的文档向量比较获取相关信息,再将问题和相关信息传递给大模型生成回答,最后展示给用户。

(二)LangChain 框架优势

LangChain + LLM 的配置简化了开发流程,使复杂的基于大语言模型的应用开发变得易于操作。在大模型和 LangChain 出现之前,实现类似功能需要更多复杂的技术和工作,而现在借助 LangChain 框架可以高效地开发出实用的问答系统等应用。