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

news2024/11/24 2:20:29

基于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 = 4096
    temperature: float = 0.8
    top_p = 0.9
    tokenizer: object = None
    model: object = None
    history = []

    def __init__(self):
        super().__init__()

    @property
    def _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)
    # 切割加载的 document
    split_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_docs

result = 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_pmt

def qa():
    llm = ChatGLM2()
    llm.load_model("/Users/**/PycharmProjects/llm/ChatGLM-6B/THUDM/chatglm-6b")
    my_pmt = define_prompt()
    result = llm(my_pmt)
    return result



if __name__ == '__main__':
    result = qa()
    print(result)


小结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1807321.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言统计分析——数据集概念和数据结构

参考资料:R语言实战.第2版 1、数据集的概念 数据集通常是由数据构成的一个矩形数组,行表示观测,列表示变量。 不同行业对于数据集的行和列叫法不同。统计学称为观测(observation)和变量(variable&#xff…

Nginx高级配置及重写功能

文章目录 一、高级配置网页的状态页Nginx第三方模块变量访问日志Nginx压缩功能https功能自定义小图标 二、重写功能(rewrite)if指令return指令set指令break指令rewrite指令防盗链 一、高级配置 网页的状态页 状态页显示的是整个服务器的状态而非虚拟主…

LabVIEW在高校中的应用

LabVIEW 作为一款功能强大的图形化编程工具,在高校中有广泛的应用。它不仅用于教学实验,还广泛应用于科研项目和工程训练。本文将从教学、科研、实验室管理和学生技能培养等多个角度,详细分析LabVIEW在高校中的应用。 教学应用 课程设计 自动…

力扣2444.统计定界子数组的数目

力扣2444.统计定界子数组的数目 观察到不满足条件的数 可以作为天然的分割线 因此在枚举右端点的过程中 预处理minK,maxK和分割线上一次出现的下标 res min(min_i,max_i) - i0; 但是因为可能在到下个区段时 min_i和max_i尚未更新 导致结果为负数 所以要跟0再取一…

《Brave New Words 》2.2 阅读理解的未来,让文字生动起来!

Part II: Giving Voice to the Social Sciences 第二部分:为社会科学发声 The Future of Reading Comprehension, Where Literature Comes Alive! 阅读理解的未来,让文字生动起来! Saanvi, a ninth grader in India who attends Khan World S…

SOA的设计模式_2.企业服务总线模式

1.企业服务总线(|Enterprise Service Bus,ESB) 在企业基于SOA实施EAI、B2B和BMP的过程中,如果采用点对点的集成方式存在着复杂度高,可管理性差,复用度差和系统脆弱等问题。企业服务总线(…

vuInhub靶场实战系列--Kioptrix Level #2

免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关。 目录 免责声明前言一、环境配置1.1 靶场信息1.2 靶场配置 二、信息收集2.1 主机发现2.1.1 netdiscover2.1.2 nmap主机扫描2.1.3 arp-scan主机扫描 2.2 端口扫描…

打字侠是一款PWA网站,如何下载到电脑桌面?

嘿,亲爱的键盘侠们! 你是否还在为寻找一款好用的打字练习工具而烦恼?别担心,今天我要给大家介绍一位超级英雄——打字侠!它不仅是一个超级酷的打字练习网站,还是一款PWA(渐进式网页应用&#x…

Python程序操作MySQL数据库教程

1.Python程序操作MySQL数据库: 使用pymysql安装包 使用: 1.导入pysql包 import pymysql 2.创建连接对象 调用pymysql模块中的connect()函数来创建连接对象,代码如下: 连接对象说明: 关闭连接 co…

JAVA:通过电信ctg.ag.sdk从电信物联平台AIOT获取设备上报数据的简单示例

一、问题场景 物联设备比如NB设备通过NB协议将数据传到电信平台后,我们的应用服务如何从电信平台获取可用的上报数据。以下通过电信开发者平台提供的SDK来简单演示下整个过程。 二、使用电信 SDK进行开发 电信AIOT物联平台提供了两种方式获取平台数据&#xff0c…

Virtual Memory Primitives for User Program翻译

Virtual Memory Primitives for User Program 安德鲁阿普尔(Andrew Appel)和李凯(Kai Li) 普林斯顿大学计算机科学系 摘要 传统上,内存管理单元(MMUS)被操作系统用于实现磁盘分页的虚拟内存…

cisco packet tracer 8.2.2 安装配置 基础教程 免登录免破解 简单方便

1 官网下载,需要账号 2 安装 3 启动之前,直接断网,禁用网卡(⊙﹏⊙) #汉化 #重新打开Cisco Packet Tracer

Apollo9.0 PNC源码学习之Control模块(一)

0 前言 从planning的角度看control,首先需要了解的就是相关的数据接口,规划出的轨迹(路径速度)发给Control模块去执行 modules/planning/planning_component/planning_component.cc planning模块发布轨迹信息 planning_writer_ …

计算机网络9——无线网络和移动网络2无线个人区域网 WPAN

文章目录 一、蓝牙系统二、低速 WPAN三、高速 WPAN 无线个人区域网WPAN(Wireless Personal Area Network)就是在个人工作的地方把属于个人使用的电子设备(如便携式电脑、平板电脑、便携式打印机以及蜂窝电话等)用无线技术连接起来自组网络,不需要使用接入点AP&#…

DP:回文串模型

一、回文子串 . - 力扣(LeetCode) 该题有3种解法 (1)中心扩展算法(在字符串章节有介绍)时间复杂度O(N^2),空间复杂度O(1) (2)马丁车…

小冬瓜AIGC 手撕LLM 拼课

小冬瓜aigc手撕LLM学习 官方认证 手撕LLMRLHF速成班-(附赠LLM加速分布式训练超长文档) 帮助多名同学上岸LLM方向,包括高校副教授,北美PhD,大厂等 课程名称【手撕LLMRLHF】 授课形式:在线会议直播讲解课后录播 时间&…

Nvidia的成功与竞争:CEO黄仁勋的自信与挑战

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【将xml文件转yolov5训练数据txt标签文件】连classes.txt都可以生成

将xml文件转yolov5训练数据txt标签文件 前言一、代码解析 二、使用方法总结 前言 找遍全网,我觉得写得最详细的就是这个博文⇨将xml文件转yolov5训练数据txt标签文件 虽然我还是没有跑成功。那个正则表达式我不会改QWQ,但是不妨碍我会训练ai。 最终成功…

LangChain基础知识入门

LangChain的介绍和入门 1 什么是LangChain LangChain由 Harrison Chase 创建于2022年10月,它是围绕LLMs(大语言模型)建立的一个框架,LLMs使用机器学习算法和海量数据来分析和理解自然语言,GPT3.5、GPT4是LLMs最先进的代…

架构设计-用户信息及用户相关的密码信息设计

将用户的基本信息和用户密码存放在不同的数据库表中是一种常见的安全做法,这种做法旨在增强数据的安全性和管理的灵活性。以下是这种做法的几个关键原因: 安全性增强: 当用户密码被单独存放在一个表中时,可以使用更强大的加密和哈…