当前位置: 首页 > news >正文

LangChain + ChatGLM 实现本地知识库问答

基于LangChain + ChatGLM 搭建融合本地知识的问答机器人


在这里插入图片描述

1 背景介绍

在这里插入图片描述

近半年以来,随着ChatGPT的火爆,使得LLM成为研究和应用的热点,但是市面上大部分LLM都存在一个共同的问题:模型都是基于过去的经验数据进行训练完成,无法获取最新的知识,以及各企业私有的知识。因此很多企业为了处理私有的知识,主要借助以下两种手段来实现:

  • 利用企业私有知识,基于开源大模型进行微调
  • 基于LangChain集成向量数据库以及LLM搭建本地知识库的问答

我们将基于LangChain+ChatGLM搭建本地知识的问答机器人系统。该系统需要能够根据用户提供的问题,在本地的知识库(离线)中查找并返回相关答案。

本次项目以"某东商品衣服"为例,以衣服属性构建本地知识,测试问答效果。使用者可以自由更新本地知识,用户问题的答案也是基于本地知识生成的。

关于ChatGLM:

ChatGLM是由清华技术成果转化的公司智谱AI研发的支持中英双语的对话机器人,ChatGLM通过建立大规模的语言模型库,并在实时数据流中进行分析和生成,以实现高效、实时的文本生成和响应;该技术可以快速对大量数据进行处理和分析,通过深度学习模型实时分析用户问题或需求,提高工作效率。

2 项目介绍

在这里插入图片描述

该项目的基本原理:

  • 加载文件
  • 读取文件
  • 文本分割
  • 文本向量化
  • 问句向量化
  • 在文本向量中匹配出与问句向量相似的top_k个
  • 匹配出的文本作为上下文和问题一起添加到prompt中
  • 提交给LLM生成答案

该问答机器人的主要功能包括:

  • 基于本地知识库的问答:系统可以根据用户的提问,在本地的知识库中进行搜索,并返回相关的答案。
  • 多模型支持:项目支持使用不同的语言模型,可以根据需求选择合适的模型进行使用。
  • 离线私有化:可以将该问答系统部署在本地环境中,确保数据的安全性和隐私性。

3 项目流程

准备本地知识库:

  • 首先,你需要一个本地知识库。这可以是一个结构化的数据库,如SQLite、MySQL等,或者是一个非结构化的文档集合,如PDF文件、文本文件等。

  • 确保你的知识库包含了你想要机器人回答的问题的相关信息。

设置LangChain环境:

  • 安装LangChain库。如果你使用的是Python,可以通过pip install langchain来安装。

集成ChatGLM
构建问答逻辑
实现与本地知识库的交互
整合ChatGLM与LangChain

4 环境配置

在这里插入图片描述

4.1 安装依赖

  • 首先,确保你的机器安装了Python3.8-Python3.11
# 终端查看python的版本
python --version
  • 紧接着安装项目的依赖
# 安装全部依赖
pip install faiss-cpu
pip install langchain
pip install qianfan

4.2 模型下载

如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 LLM 与 Embedding 模型可以从 HuggingFace 下载。

本项目中默认使用的 LLM 模型 THUDM/ChatGLM-6B 与 Embedding 模型 moka-ai/m3e-base

5 代码实现

在这里插入图片描述

5.1 自定义GLM类

  • 目的:使用LLMs模块封装ChatGLM,load本地模型。使用LLM模块封装我们的模型接口的一个好处是有利于后续跟LangChain的其他模块协同。

  • 代码路径:/Users/**/PycharmProjects/llm/langchain_apply/Knowledge_QA/model.py

  • 具体代码

  • 导入必备的工具包

from langchain.llms.base import LLM
from langchain.llms.utils import enforce_stop_tokens
from transformers import AutoTokenizer, AutoModel
from typing import List, Optional
  • 自定义GLM类
# 自定义ChatGLM2
class ChatGLM2(LLM):max_token: int = 4096temperature: float = 0.8top_p = 0.9tokenizer: object = Nonemodel: object = Nonehistory = []def __init__(self):super().__init__()@propertydef _llm_type(self) -> str:return "ChatGLM2"# 定义load_model方法,进行模型的加载def load_model(self, model_path=None):self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)self.model = AutoModel.from_pretrained(model_path, trust_remote_code=True).float()# 实现_call方法,进行模型的推理def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:response, _ = self.model.chat(self.tokenizer,prompt,history=self.history,max_length=self.max_token,temperature=self.temperature,top_p=self.top_p)if stop is not None:response = enforce_stop_tokens(response, stop)self.history = self.history + [[None, response]]return response

5.2 构建Faiss索引

  • 目的:构建向量库

  • 代码位置:/Users/**/PycharmProjects/llm/langchain_apply/Knowledge_QA/get_vector.py

  • 具体代码

  • 导入必备的工具包

from langchain.document_loaders import UnstructuredFileLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS # 向量数据库
  • 定义main()方法

def main():# 定义向量模型路径EMBEDDING_MODEL = "moka-ai/m3e-base"# 第一步:加载文档loader = UnstructuredFileLoader("衣服属性.txt")# 将文本转成 Document 对象data = loader.load()print(f'documents:{len(data)}')# 第二部:切分文本text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=0)# 切割加载的 documentsplit_docs = text_splitter.split_documents(data)# print("split_docs size:",len(split_docs))# print(split_docs)# 第三步:初始化 hugginFace 的 embeddings 对象embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)# 第四步:将 document通过embeddings对象计算得到向量信息并永久存入FAISS向量数据库,用于后续匹配查询db = FAISS.from_documents(split_docs, embeddings)db.save_local("./faiss/product")return split_docsresult = main()
print(result)

在这里插入图片描述

5.3 实现QA本地知识库问答

  • 代码路径:/Users/ligang/PycharmProjects/llm/langchain_apply/Knowledge_QA/main.py
  • 代码实现
# coding:utf-8
# 导入必备的工具包
from langchain import PromptTemplate
from get_vector import *
from model import ChatGLM2
# 加载FAISS向量库
EMBEDDING_MODEL = "moka-ai/m3e-base"
embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)
db = FAISS.load_local("faiss/product",embeddings)def get_related_content(related_docs):related_content = []for doc in related_docs:related_content.append(doc.page_content.replace("\n\n", "\n"))return "\n".join(related_content)def define_prompt():question = '我身高170,体重140斤,买多大尺码'docs = db.similarity_search(question, k=1)related_content = get_related_content(docs)PROMPT_TEMPLATE = """基于以下已知信息,简洁和专业的来回答用户的问题。不允许在答案中添加编造成分。已知内容:{context}问题:{question}"""prompt = PromptTemplate(input_variables=["context", "question"],template=PROMPT_TEMPLATE,)my_pmt = prompt.format(context=related_content,question=question)return my_pmtdef qa():llm = ChatGLM2()llm.load_model("/Users/**/PycharmProjects/llm/ChatGLM-6B/THUDM/chatglm-6b")my_pmt = define_prompt()result = llm(my_pmt)return resultif __name__ == '__main__':result = qa()print(result)

小结

主要介绍了基于LangChain+ChatGLM-6B模型实现本地知识库的问答实现原理+过程。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【C++】函数模板和类模版
  • 《精通ChatGPT:从入门到大师的Prompt指南》附录C:专业术语表
  • SpringBoot+Vue实现前后端分离基本的环境搭建
  • 王学岗鸿蒙开发(北向)——————(七、八)ArkUi的各种装饰器
  • Kafka 架构
  • 快速排序(Quick_Sort)
  • python一点通: Async异步函数很好,但是如何有效执行阻塞任务?
  • chatgpt 推荐的一些关于提高认知的书,我先存一下
  • OJ3829大石头的搬运工
  • 定时器更新界面,线程报错
  • Hack The Box(黑客盒子)Redeemer篇
  • C++设计模式-外观模式,游戏引擎管理多个子系统,反汇编
  • STM32F103C8移植uCOSIII并以不同周期点亮两个LED灯(HAL库方式)【uCOS】【STM32开发板】【STM32CubeMX】
  • 软件测试--第六章、系统功能测试
  • 自动化专业之半导体行业入门指南
  • const let
  • crontab执行失败的多种原因
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • java第三方包学习之lombok
  • Java-详解HashMap
  • JS学习笔记——闭包
  • mac修复ab及siege安装
  • Python 反序列化安全问题(二)
  • python 装饰器(一)
  • React16时代,该用什么姿势写 React ?
  • Sass Day-01
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • uva 10370 Above Average
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 诡异!React stopPropagation失灵
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 智能合约Solidity教程-事件和日志(一)
  • 2017年360最后一道编程题
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • #13 yum、编译安装与sed命令的使用
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • #知识分享#笔记#学习方法
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (35)远程识别(又称无人机识别)(二)
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (每日一问)基础知识:堆与栈的区别
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (一一四)第九章编程练习
  • (转)visual stdio 书签功能介绍
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET : 在VS2008中计算代码度量值
  • .net MySql
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 发展历程
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET 设计模式初探