基于LangChain框架搭建知识库

2024-06-24 06:36

本文主要是介绍基于LangChain框架搭建知识库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于LangChain框架搭建知识库

  • 说明
  • 流程
    • 1.数据加载
    • 2.数据清洗
    • 3.数据切分
    • 4.获取向量
    • 5.向量库保存到本地
    • 6.向量搜索
    • 7.汇总调用

说明

本文使用openai提供的embedding模型作为框架基础模型,知识库的搭建目的就是为了让大模型减少幻觉出现,实现起来也很简单,假如你要做一个大模型的客服问答系统,那么就把历史客服问答数据整理好,先做数据处理,在做数据向量化,最后保存到向量库中就可以了,下面文章中只是一个简单工作流程,只能用来参考,希望对大家有所帮助!

流程

上传知识库的文档不限于txt,pdf,markdown等数据格式,不同的数据格式用不同的方法来处理,文章内仅使用pdf文件做测试

1.数据加载

def load_data():from langchain.document_loaders.pdf import PyMuPDFLoader# 本地pdf文档路径loader = PyMuPDFLoader("./knowledge_db/pumkin_book/pumpkin_book.pdf")pdf_pages = loader.load()print(f"载入后的变量类型为:{type(pdf_pages)},", f"该 PDF 一共包含 {len(pdf_pages)} 页")pdf_page = pdf_pages[1]page_content = pdf_page.page_contentprint(f"每一个元素的类型:{type(pdf_page)}.",f"该文档的描述性数据:{pdf_page.metadata}",f"查看该文档的内容:\n{pdf_page.page_content}",sep="\n------\n")return page_content,pdf_pages

2.数据清洗

def clean_data(pdf_content):# 匹配非中文字符和换行符pattern = re.compile(r'[^\u4e00-\u9fff](\n)[^\u4e00-\u9fff]', re.DOTALL)# 将匹配到的换行符替换为空字符串new_pdf_content = re.sub(pattern, lambda match: match.group(0).replace('\n', ''), pdf_content)# 去除。和空格符号new_pdf_content = new_pdf_content.replace('。', '').replace(' ', '')return new_pdf_content

3.数据切分

def split_data(pdf_pages,new_pdf_content):'''* RecursiveCharacterTextSplitter 递归字符文本分割RecursiveCharacterTextSplitter 将按不同的字符递归地分割(按照这个优先级["\n\n", "\n", " ", ""]),这样就能尽量把所有和语义相关的内容尽可能长时间地保留在同一位置RecursiveCharacterTextSplitter需要关注的是4个参数:* separators - 分隔符字符串数组* chunk_size - 每个文档的字符数量限制* chunk_overlap - 两份文档重叠区域的长度* length_function - 长度计算函数'''from langchain.text_splitter import RecursiveCharacterTextSplitter# 知识库中单段文本长度CHUNK_SIZE = 500# 知识库中相邻文本重合长度OVERLAP_SIZE = 50# 使用递归字符文本分割器text_splitter = RecursiveCharacterTextSplitter(chunk_size=CHUNK_SIZE,chunk_overlap=OVERLAP_SIZE)text_splitter.split_text(new_pdf_content[0:1000])split_docs = text_splitter.split_documents(pdf_pages)print(f"切分后的文件数量:{len(split_docs)}")print(f"切分后的字符数(可以用来大致评估 token 数):{sum([len(doc.page_content) for doc in split_docs])}")return split_docs

4.获取向量

def gpt_config():import httpx# 使用httpx设置代理proxy = 'http://127.0.0.1:8080' # 修改为自己的代理地址proxies = {'http://': proxy, 'https://': proxy}http_client = httpx.Client(proxies=proxies, verify=True)return http_clientdef get_vector(split_docs):# from langchain.embeddings import OpenAIEmbeddingsfrom langchain_openai import OpenAIEmbeddingsfrom langchain.vectorstores.chroma import Chromafrom dotenv import load_dotenv, find_dotenv# 获取key_ = load_dotenv(find_dotenv()) # 可注释api_key = os.environ.get("OPENAI_API_KEY")http_client = gpt_config()# 官网有提供3个embedding模型,按需选择embedding = OpenAIEmbeddings(model="text-embedding-3-small",openai_api_key=api_key,http_client=http_client)# 保存路径persist_directory = './vector_db/chroma'vectordb = Chroma.from_documents(documents=split_docs[:20],  # 为了速度,只选择前 20 个切分的 doc 进行生成embedding=embedding,persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上)return vectordb

5.向量库保存到本地

def save_vector(vectordb):vectordb.persist()print(f"向量库中存储的数量:{vectordb._collection.count()}")

6.向量搜索

def search_vector(vectordb):question = '什么是机器学习'# 余弦相似度搜索search_result = vectordb.similarity_search(question, k=2) # k表示返回的相似文档数量print(f"检索到的内容数:{len(search_result)}")for i, sim_doc in enumerate(search_result):print(f"检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")# MMR搜索# 核心思想是在已经选择了一个相关性高的文档之后,再选择一个与已选文档相关性较低但是信息丰富的文档。这样可以在保持相关性的同时,增加内容的多样性,避免过于单一的结果。mmr_docs = vectordb.max_marginal_relevance_search(question, k=2)for i, sim_doc in enumerate(mmr_docs):print(f"MMR 检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")

7.汇总调用

def main_task():# 加载数据pdf_content,pdf_pages = load_data()# 数据清洗new_pdf_content = clean_data(pdf_content)# 切分数据split_docs = split_data(pdf_pages,new_pdf_content)# 获取向量vectordb = get_vector(split_docs)# 将向量库内容保存到本地文件中# save_vector(vectordb)# 向量搜索search_vector(vectordb)

这篇关于基于LangChain框架搭建知识库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089428

相关文章

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Java 与 LibreOffice 集成开发指南(环境搭建及代码示例)

《Java与LibreOffice集成开发指南(环境搭建及代码示例)》本文介绍Java与LibreOffice的集成方法,涵盖环境配置、API调用、文档转换、UNO桥接及REST接口等技术,提供... 目录1. 引言2. 环境搭建2.1 安装 LibreOffice2.2 配置 Java 开发环境2.3 配

Python极速搭建局域网文件共享服务器完整指南

《Python极速搭建局域网文件共享服务器完整指南》在办公室或家庭局域网中快速共享文件时,许多人会选择第三方工具或云存储服务,但这些方案往往存在隐私泄露风险或需要复杂配置,下面我们就来看看如何使用Py... 目录一、android基础版:HTTP文件共享的魔法命令1. 一行代码启动HTTP服务器2. 关键参

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是