使用GPT3.5,LangChain,FAISS和python构建一个本地知识库

引言

  • 介绍本地知识库的概念和用途

在现代信息时代,我们面临着海量的数据和信息,如何有效地管理和利用这些信息成为一项重要的任务。本地知识库是一种基于本地存储的知识管理系统,旨在帮助用户收集、组织和检索大量的知识和信息。它允许用户在本地环境中构建和管理自己的知识资源,以便更高效地进行信息处理和决策。

本地知识库通常采用数据库、索引和搜索技术,以构建一个结构化的存储系统,使用户可以快速地访问和查询所需的信息。

  • 引出使用GPT-3.5、LangChain和FAISS构建本地知识库的动机

当面临一个知识类问题时,我们往往需要利用自己获取到的信息加以总结,对海量信息中包含的要点进行快速地查询和了解,而现在出现的GPT-3.5技术则能够使得用户向语言模型提问并得到一个回答。LangChain则是对大语言模型技术所用到的一些功能进行了统一的封装,这使得我们可以利用本地的知识资源,以获得我们需要的信息,FAISS则是一个可以存储这种类型数据的向量数据库。

ChatGPT

ChatGPT 是由 OpenAI 开发的一种高级语言模型,可以根据给定的提示生成类似人类语言的文本,从而实现对话、文本摘要和问答等多种功能。

出于演示的目的,我们将专注于OpenAI的"gpt-3.5-turbo-16k"模型,因为它目前价格合适,速度较快,回答比较准确。

如果想深入了解chatgpt相关信息,请参考下面链接:

https://platform.openai.com/docs/api-reference

LangChain

LangChain 是一个库(以 Python、JavaScript 或 TypeScript 提供),提供了一组用于处理语言模型、文本嵌入和文本处理任务的工具和实用程序。 它通过组合语言模型、向量存储和文档加载器等各种组件来简化创建聊天机器人、处理文档检索和执行问答操作等任务。

img

我们将专注于创建一个问答聊天机器人,其中包含上面图中所展示的绿色的部分。

如果想深入了解LangChain相关信息,请参考下面链接:

https://python.langchain.com/docs/get_started

FAISS

FAISS(Facebook AI相似性搜索)是Facebook AI Research开发的开源库。 它旨在有效地搜索大量高维数据中的相似项(向量)。 FAISS 提供了索引和搜索向量的方法,使您可以更轻松、更快速地找到数据集中最相似的项目。现在的一个简单理解是,FAISS并不能直接存储数据,它只是一个索引和搜索向量的工具,这个工具可以根据emdebbing的后生成的向量,从文本中匹配跟问题相关的内容出来。FAISS的存储数据只是把向量化后的一系列数据存在本地文件,之后需要的时候再从本地文件进行加载进去。所以我们设计的时候应该得分成两步进行设计,一部分是生成本地文件的代码,一部分是加载本地文件的代码,当然加载本地文件就是直接写在业务代码里面,不需要单独拆出来了。

它在以下任务中特别有用:

  • 推荐系统
  • 信息检索
  • 聚类——找到相似的项目很重要

如果您有一个基本的聊天机器人并且满足以下条件,那么 FAISS 是一个可靠的矢量存储选择:

  • 查询可由CPU支持的有限数据集
  • 寻求免费开源的矢量存储解决方案
  • 不打算在您的架构中引入其他服务器或云 API

如果想深入了解FAISS相关信息,请参考下面链接:

https://faiss.ai/

Document loaders

Document loaders是langchain中的一个组件,它的功能是从文件中读取数据,比如PDF,csv,url,txt等。经过loaders加载后的数据Document主要由两部分组成,即page_content和metadata。metadata中存储了文件名,第几页等基础信息,page_content中存储了该页的内容。

其基础用法如下:

from langchain.document_loaders import PyPDFLoader 
loader = PyPDFLoader(r"loRA _refer.pdf") 
print(loader.load()

代码解释:

  1. PyPDFLoader是document_loaders 中加载pdf的组件,这段代码将pdf加载为一个loader对象,并打印了其中内容,可以看出打印为一个列表,这个列表中存放了一个Document对象。
  2. 除了PyPDFLoader,langchain还提供了

CSVLoader,HTMLLoader,JSONLoader,MarkdownLoader,File Directory,ExcelLoader,Microsoft Word,Microsoft PowerPoint,GitHub,EPub,Images,WebBaseLoader,URL等多种加载器,具体可查看其document_loaders文档:

https://python.langchain.com/docs/modules/data_connection/document_loaders/

File Directory loader

File Directory loader可以从文件夹中同时加载多个文件,其基本用法如下:

from langchain.document_loaders import DirectoryLoader,PyPDFLoader 
 
loader_pdf=DirectoryLoader('./docs/',glob="**/*.pdf",loader_cls=PyPDFLoader)
 
documents = loader_pdf.load()

代码解释:

  1. from langchain.document_loaders import DirectoryLoader: 这行代码从langchain.document_loaders 模块中导入 DirectoryLoader类。DirectoryLoader类是用于从目录加载文档的工具。
  2. loader_pdf = DirectoryLoader('./docs/', glob="**/*.pdf", loader_cls= PyPDFLoader): 这行代码创建一个名为loader_pdf的对象,它是DirectoryLoader类的一个实例。构造函数的参数如下所示:
    1. './docs/': 这是要加载的目录路径,即包含PDF文档的目录。在这个例子中,路径为'./docs/',表示当前目录下的docs文件夹。
    2. glob="**/*.pdf": 这是一个用于匹配文件的通配符模式。在这里,**/*.pdf表示匹配任意目录下的任意文件名以.pdf结尾的文件。
    3. loader_cls=PyPDFLoader: 这是一个指定要使用的加载器类的参数。在这个例子中,指定的加载器类是PyPDFLoader。最佳实践为,当明确需要加载文件类型时,应该明确指定这里的loader_cls,即加载器是什么。
  3. documents = loader_pdf.load(): 这行代码使用之前创建的loader_pdf对象调用load()方法来加载文档。load()方法将根据之前设置的目录路径、文件匹配模式和加载器类来加载满足条件的PDF文档,并将加载的文档存储在名为documents的变量中。

Document transformers

因为在现在的技术条件下,chatgpt或其他的大语言模型均有受到文本长度的限制,所以对于一个大型文件或者很多个大型文件时,若将全部文本一次性发送给chatgpt,则模型往往会报错token超出。在这种情况下,我们则会先将长文档拆分为可以放入模型上下文窗口的较小块。在langchain中内置了很多函数,使我们可以直接进行这个操作。、

from langchain.document_loaders import DirectoryLoader,PyPDFLoader 
from langchain.text_splitter import CharacterTextSplitter loader_pdf=DirectoryLoader('./docs/',glob="**/*.pdf",loader_cls=PyPDFLoader) 
documents = loader_pdf.load() 
text_splitter=CharacterTextSplitter(chunk_size=1000,chunk_overlap=0) 
docs = text_splitter.split_documents(documents)

代码解释:

  1. text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0): 这行代码创建一个名为text_splitter的对象,它是CharacterTextSplitter类的一个实例。构造函数的参数如下所示:
    1. chunk_size=1000: 这是指定拆分文本片段的大小的参数。在这里,设置为1000,表示每个片段的字符数为1000。
    2. chunk_overlap=0: 这是指定片段之间重叠部分的大小的参数。在这里,设置为0,表示片段之间没有重叠。设置重叠部分有可能会在某些长句子面临被切开情况会很有用,或者上下两句联系较为紧密时起作用。可以根据实际情况来写入,默认可以设置为0.
  2. docs = text_splitter.split_documents(documents): 这行代码使用之前创建的text_splitter对象调用split_documents()方法来将加载的文档拆分成较小的文本片段。拆分后的文本片段将存储在名为docs的变量中。split_documents()方法的参数documents是之前加载的文档。

Text embedding models

embedding (嵌入)这个动作的目的是创建一段文本的矢量表示形式。矢量是一个数学领域的概念,若对这部分不熟悉请学习线性代数这门课程。

矢量在数学上一般以一个有序数组来表示,相关概念见下文:

https://zhuanlan.zhihu.com/p/339974158

文本向量化之后,就可以执行诸如语义搜索之类的操作,在其中我们可以寻找向量空间中最相似的文本片段。

当我们需要查找向量空间的最相似的文本片段时,就必须引入另一个工具,即向量数据库。

Vector stores

存储和搜索非结构化数据的最常见方法之一是将数据embedding并存储生成的embedding向量。然后在查询时检索与查询内容"最相似"的embedding向量。Vector stores(矢量存储)负责存储embedding数据并为您执行矢量搜索。(请注意,在数学中矢量与向量同义)。

from langchain.document_loaders import DirectoryLoader,PyPDFLoader
from langchain.text_splitter import CharacterTextSplitter 
 
loader_pdf=DirectoryLoader('./docs/',glob="**/*.pdf",loader_cls=PyPDFLoader) 
documents = loader_pdf.load() 
text_splitter=CharacterTextSplitter(chunk_size=1000,chunk_overlap=0)
docs = text_splitter.split_documents(documents) 
faissIndex = FAISS.from_documents(docs, OpenAIEmbeddings()) 
 
faissIndex.save_local("faiss_midjourney_docs")
  1. 从文档块创建 FAISS 索引,使用 OpenAIEmbeddings() 将文本块转换为矢量表示形式,并生成一个faiss对象.
  2. 将创建的 FAISS 索引保存到名为"faiss_midjourney_docs"的本地文件中。然后,该索引可以重新用于将来的高效相似性搜索任务,而不需要重新从源文件中生成。

这个"faiss_midjourney_docs"的本地文件实际上是一个文件夹,其目录结构如下图:

img

从本地加载 FAISS 索引并加入到langchain的问答中

import os, dotenv 
from langchain.embeddings.openai import OpenAIEmbeddings 
from langchain.vectorstores import FAISS 
from langchain.chat_models import ChatOpenAI 
from langchain.chains import RetrievalQA 
from langchain import PromptTemplate 
 
dotenv.load_dotenv() 
 
chatbot = RetrievalQA.from_chain_type( 
    llm=ChatOpenAI( 
        openai_api_key=os.getenv("OPENAI_API_KEY"), 
        temperature=0, model_name="gpt-3.5-turbo", max_tokens=50 
    ),
    chain_type="stuff", 
    retriever=FAISS.load_local("faiss_midjourney_docs", OpenAIEmbeddings())          
        .as_retriever(search_type="similarity", search_kwargs={"k":1}) 
    ) 
 
template = """ 
respond as succinctly as possible. {query}? 
""" 
 
prompt = PromptTemplate( 
    input_variables=["query"], 
    template=template, 
) 
 
print(chatbot.run( 
    prompt.format(query="what is --v") 
))
  1. 导入必要的库和模块,包括 os 、、 OpenAIEmbeddingsFAISS dotenv RetrievalQAChatOpenAIPromptTemplate
  2. 使用 从 dotenv .env 文件加载环境变量(即 OPENAI_API_KEY)。
  3. 使用 GPT-3.5-turbo 模型初始化 ChatOpenAI 实例,温度为 0,最多 50 个响应令牌和 OpenAI API 密钥。默认温度为 0.7 — 将值设置为 0 将降低 ChatGPT 完成的随机性。
  4. 使用 加载 OpenAIEmbeddings 预构建的 FAISS 索引“faiss_midjourney_docs”。
  5. 设置包含 RetrievalQA ChatOpenAI 实例、FAISS 索引以及搜索类型和参数的链。强烈建议设置 search_typesearch_kwargs - 不这样做将具有成本效益,因为向量存储中的所有块都将发送到LLM。还值得注意的是, chain_type 是“东西”它试图将所有块填充到提示中作为您的LLM(即ChatGPT)的上下文。
  6. 定义一个包含变量“query”的提示模板,并要求提供简洁的答案。
  7. 使用定义的模板创建 PromptTemplate 实例。
  8. 使用与中途相关的查询来设置提示的格式。
  9. 使用格式化的提示问题执行聊天机器人。
  10. 打印聊天机器人的答案。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习驱动智能超材料设计与应用

在深度学习与超材料融合的背景下,不仅提高了设计的效率和质量,还为实现定制化和精准化的治疗提供了可能,展现了在材料科学领域的巨大潜力。深度学习可以帮助实现超材料结构参数的优化、电磁响应的预测、拓扑结构的自动设计、相位的预测及结构…

软件测试——非功能测试

工作职责: 1.负责产品系统测试,包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写,包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求: 1.熟练…

数据可视化在智慧医疗中的重要应用

在现代智慧医疗的推动下,数据可视化技术正日益成为医疗领域的重要工具。通过将复杂的医疗数据转换为直观的图表和图形,数据可视化不仅提升了医疗服务的效率,还极大地改善了患者的就医体验。 在智慧医疗中,数据可视化首先在电子病历…

知识图谱和 LLM:利用Neo4j驾驭大型语言模型(探索真实用例)

这是关于 Neo4j 的 NaLLM 项目的一篇博客文章。这个项目是为了探索、开发和展示这些 LLM 与 Neo4j 结合的实际用途。 2023 年,ChatGPT 等大型语言模型 (LLM) 因其理解和生成类似人类的文本的能力而风靡全球。它们能够适应不同的对话环境、回答各种主题的问题,甚至模拟创意写…

实时系统Preempt RT与Xenomai之争!谁更主流,谁更实时

版权声明:本文主要内容基于“北京盟通科技有限公司”授权提供的文件,由“创龙科技”进行整理得出。感谢“盟通科技”的慷慨支持,让更多人了解Linux系统的“实时拓展”选择知识。 选择争论一直存在 大家知道EtherCAT是实时现场总线技术&…

Java中使用加密盐

0 前言 众所周知,密码肯定不能用明文存储。 之前一直使用MD5进行加密,现在才知道有彩虹表这回事。所以记录一下对应的处理方式:加密盐。 1 彩虹表 例如用MD5加密,随便没法破解,但是有些常用的字符被收集到彩虹表里…

OSU!题解(概率dp)

题目:OSU! - 洛谷 思路: 设E()表示截止到i所获得的分数; 对于到i点的每一个l,如果第i1点为1,那么会新增分数3*l^23*l1; 就有递推公式方程: E()E()p[i1]p*(3*l^23*l1);(p代表截止到i获得长度l的概率)&a…

关于mybatis中语法的错误记录

大家注意再写mybatis时候的逗号,虽然不起眼,但是会一直报错,最后一个字段不需要逗号,其余字段全部需要逗号。

【个人笔记】685. 冗余连接 II 的解释(并查集)

一棵树有n个点和n条边,返回一条能删除的边,使得剩下的图是有 n 个节点的有根树。 解释: 注意不冗余的有根树的特性!**根节点入度为0,其余结点只有一个入度!**所以冗余的两种情况如下: &#xff…

Vue3项目基于Axios封装request请求

在 Vue 3 的项目开发中,使用 Axios 进行 HTTP 请求是非常常见的作法,为了更方便开发者更高效的进行代码编写和项目的维护,可以通过再次封装 Axios 来实现。 在本文中,博主将详细指导你如何在自己的 Vue 3 项目中使用 Axios 二次封…

Vue学习---vue cli 项目创建

使用的编辑工具webStorm 创建例子: hello vue create hello 选择 vue3 进行创建 运行 npm run serve 测试访问:http://localhost:8080 改动内容重新编译: npm run build dist 目录就是编译后的可运行内容

客流统计系统优化景区服务流程,增强游客满意度

在当今旅游业蓬勃发展的时代,景区面临着越来越多的挑战和机遇。如何提供更优质、更高效的服务,满足游客日益增长的需求,成为了景区管理者们关注的焦点。客流统计系统作为一种创新的技术手段,正逐渐成为优化景区服务流程、增强游客…

windows 打包pyd文件

1.新建一个py文件,myunit.py,里面的代码是: class Adder: def __init__(self, a, b): self.a a self.b b def add(self): return self.a self.b 2.新建一个py文件,setup.py,里面的代码是: from setuptools import setup fro…

巧用通义灵码助力护网面试

前言 前几年护网还算是一个比较敏感的话题,但是随着近段时间的常态化开始,护网行动也是逐渐走进了大众的视野,成为了社会各界共同关注的安全盛事。本篇也是受通义灵码备战求职季活动的启发,结合近期要开始的护网行动&#xff0c…

持续集成06--Jenkins构建触发器

前言 在持续集成(CI)的实践中,构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程,从而确保代码变更能够及时地得到验证和反馈。Jenkins,作为业界领先的CI/CD工具,提供了多种构建触发器选项…

2.I/O口

I/O输出(点灯) 分析电路 看电路图&#xff0c;元器件形成电压差&#xff0c;即可点亮LED灯 代码编写 使用不同操作进行LED控制 #include "reg52.h" //51单片机头文件 #include <intrins.h> sbit LED1 P1^0; //引脚初始化&#xff1a;P1^0&#xff1a;对应引脚…

RocketMQ~架构与工作流程了解

简介 RocketMQ 具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统&#xff0c;由阿里巴巴团队开发&#xff0c;在 2016 年底贡献给 Apache&#xff0c;成为了 Apache 的一个顶级项目。 在阿里内部&#xff0c;RocketMQ 很好地服务了集…

字符串类中的常用方法

1 string对象的创建 静态创建 String s1  "abc";  String s2  "abc";  动态创建 String s3  new String("abc"); String s4  new String("abc"); 2string对象的不可变性 任何一个String对象在创建之后都不能对它的…

甲方建设项目的数智化管理

在军工、石化、电力、民航、食品等大型集团企业和政府机构中&#xff0c;基建、IT、技改等各类固定投资项目属于甲方建设型项目。这类项目无论是EPC总包还是按合同分包&#xff0c;都具有业主型、项目干系人多、跨组织协作频繁、全生命周期管理复杂等特点。如何高效地管理这些甲…

基于LAMMPS模拟岩石表面润湿性

润湿性是指不相混的两相流体与岩石固相表面接触时&#xff0c;其中一相流体沿着岩石表面铺开的现象&#xff0c;该相称为润湿相。润湿性一般采用接触角法来确定&#xff0c;通常根据水在固体表面的角度θ来定义系统的润湿性&#xff0c;接触角为0&#xff5e;75为水润湿&#x…