LangChain知识库构建与RAG设计

RAG:检索增强生成是什么?

RAG的主要流程

Retrieval-Augmented Generation: 检索增强生成

能够根据问题的特点还有上下文, 生成更加个性化和精确的回答

  • 为LLM提供来自外部知识源的额外信息的概念。这允许它们生成更准确和有上下文的答案,同时减少幻觉
  • (1)检索:外部相似搜索 (2)增强:提示词更新 (3)生成:更详细的提示词输入LLM
  • 主要流程: 输入问题-> Retrieval检索向量数据库 -> 得到Context上下文 -> 生成详细的prompt提示 -> 再根据LLM生成对应的回答 -> 最后返回给用户

LangChain中RAG中的Retrieve实现

  • Source: 很多数据源的支持
    • github
    • YouTube
    • discord
    • Twitter
    • PPT等等
  • Loader: 对Source数据源Load到LangChain这个系统里面
  • Transform: 对数据进行向量转化, 对不同数据格式进行转化
  • Embedding: 向量化, 嵌入到向量空间
  • Store: 将向量数据存储到向量数据库里面
  • Retrieve: 通过Retrieve方式进行检索

Loader: 让大模型具备实时学习能力

Loader加载MarkDown文件

# 我是一个markdown加载示例
- 第一项目
- 第二个项目
- 第三个项目## 第一个项目
AI研习社最厉害专业的AI研究基地## 第二个项目
AIGC打造未来AI应用天地## 第三个项目
AI研习社是一个非常牛逼的AI媒体
#使用loader来加载markdown文本
from langchain.document_loaders import TextLoaderloader = TextLoader("loader.md")
loader.load()

输出:

[Document(page_content='# 我是一个markdown加载示例\n- 第一项目\n- 第二个项目\n- 第三个项目\n\n## 第一个项目\nAI研习社最厉害专业的AI研究基地\n\n## 第二个项目\nAIGC打造未来AI应用天地\n\n## 第三个项目\nAI研习社是一个非常牛逼的AI媒体', metadata={'source': 'loader.md'})]

Loader加载CVS文件

loader.csv

#使用loader来加载cvs文件
from langchain.document_loaders.csv_loader import CSVLoader#loader = CSVLoader(file_path="loader.csv")loader = CSVLoader(file_path="loader.csv",source_column="Location")
data = loader.load()
print(data)

输出:

[Document(page_content='\ufeffProject: AI GC培训\nDES: 培训课程\nPrice: 500\nPeople: 100\nLocation: 北京', metadata={'source': '北京', 'row': 0}), Document(page_content='\ufeffProject: AI工程师认证\nDES: 微软AI认证\nPrice: 6000\nPeople: 200\nLocation: 西安', metadata={'source': '西安', 'row': 1}), Document(page_content='\ufeffProject: AI应用大会\nDES: AI应用创新大会\nPrice: 200门票\nPeople: 300\nLocation: 深圳', metadata={'source': '深圳', 'row': 2}), Document(page_content='\ufeffProject: AI 应用咨询服务\nDES: AI与场景结合\nPrice: 1000/小时\nPeople: 50\nLocation: 香港', metadata={'source': '香港', 'row': 3}), Document(page_content='\ufeffProject: AI项目可研\nDES: 可行性报告\nPrice: 20000\nPeople: 60\nLocation: 上海', metadata={'source': '上海', 'row': 4})]

Loader加载Excel文件

安装插件:

! pip install "unstructured[xlsx]"

示例:将example目录下的所有*.xlsx文件都加载进来

#某个目录下,有excel文件,我们需要把目录下所有的xlxs文件加载进来
#! pip install "unstructured[xlsx]"from langchain.document_loaders import DirectoryLoader#目录下的.html和.rst文件不会被这种loader加载
#loader = DirectoryLoader("目录地址",glob="指定加载说明格式的文件")
loader = DirectoryLoader(path="./example/",glob="*.xlsx")
docs = loader.load()
len(docs)

Loader加载HTML

#使用loader来加载html文件
#from langchain.document_loaders import UnstructuredHTMLLoader# 包含代码
#loader = UnstructuredHTMLLoader("loader.html")
# 只加载文本信息
from langchain.document_loaders import BSHTMLLoader
loader = BSHTMLLoader("loader.html")
data = loader.load()
data

Loader加载json数据

安装插件:

! pip install jq
#使用loader来加载json文件
#需要先安装 ! pip install jqfrom langchain.document_loaders import JSONLoader
loader = JSONLoader(file_path = "simple_prompt.json",jq_schema=".template",text_content=True
)
data = loader.load()
print(data)

Loader加载pdf文件

安装:

! pip install pypdf
#loader加载pdf文件from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("loader.pdf")
pages = loader.load_and_split()
pages[0]

LangChain文档转换实战

  • 文档切割器和按字符分割
  • 代码文档分割器
  • 按token分割文档
  • 文档总结、精炼、翻译

原理:

  1. 将文档分成小的、有意义的块(句子).
  2. 将小的块组合成为一个更大的块,直到达到一定的大小.
  3. 一旦达到一定的大小,接着开始创建与下一个块重叠的部分.

第一个文档切割

from langchain.text_splitter import RecursiveCharacterTextSplitter#加载要切割的文档
with open("test.txt") as f:zuizhonghuanxiang = f.read()#初始化切割器
text_splitter = RecursiveCharacterTextSplitter(chunk_size=50,#切分的文本块大小,一般通过长度函数计算chunk_overlap=20,#切分的文本块重叠大小,一般通过长度函数计算length_function=len,#长度函数,也可以传递tokenize函数add_start_index=True,#是否添加起始索引
)text = text_splitter.create_documents([zuizhonghuanxiang])
print(text[0])
print(text[1])

字符串切割

from langchain.text_splitter import CharacterTextSplitter#加载要切分的文档
with open("test.txt") as f:zuizhonghuanxiang = f.read()#初始化切分器
text_splitter = CharacterTextSplitter(separator="。",#切割的标志字符,默认是\n\nchunk_size=50,#切分的文本块大小,一般通过长度函数计算chunk_overlap=20,#切分的文本块重叠大小,一般通过长度函数计算length_function=len,#长度函数,也可以传递tokenize函数add_start_index=True,#是否添加起始索引is_separator_regex=False,#是否是正则表达式
)
text = text_splitter.create_documents([zuizhonghuanxiang])
print(text[0])

代码文档切割

from langchain.text_splitter import (RecursiveCharacterTextSplitter,Language,
)#支持解析的编程语言
#[e.value for e in Language]#要切割的代码文档
PYTHON_CODE = """
def hello_world():print("Hello, World!")
#调用函数
hello_world()
"""
py_spliter = RecursiveCharacterTextSplitter.from_language(language=Language.PYTHON,chunk_size=50,chunk_overlap=10,
)
python_docs = py_spliter.create_documents([PYTHON_CODE])
python_docs

按token切割文档

from langchain.text_splitter import CharacterTextSplitter#要切割的文档
with open("test.txt") as f:zuizhonghuanxiang = f.read()#初始化切分器
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=4000,#切分的文本块大小,一般通过长度函数计算chunk_overlap=30,#切分的文本块重叠大小,一般通过长度函数计算
)text = text_splitter.create_documents([zuizhonghuanxiang])
print(text[0])

文档的总结、精炼和翻译

安装插件:

! pip install doctran==0.0.14
#加载文档
with open("letter.txt") as f:content = f.read()
from dotenv import load_dotenv
import os
load_dotenv("openai.env")
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
OPENAI_API_BASE = os.environ.get("OPENAI_PROXY")
OPENAI_MODEL = "gpt-4"
OPENAI_TOKEN_LIMIT = 8000from doctran import Doctran
doctrans = Doctran(openai_api_key=OPENAI_API_KEY,openai_model=OPENAI_MODEL,openai_token_limit=OPENAI_TOKEN_LIMIT
)
documents = doctrans.parse(content=content)
#总结文档
summary = documents.summarize(token_limit=100).execute()
print(summary.transformed_content)

输出结果:

#翻译一下文档
translation = documents.translate(language="chinese").execute()
print(translation.transformed_content)

输出结果:

#精炼文档,删除除了某个主题或关键词之外的内容,仅保留与主题相关的内容
refined = documents.refine(topics=["marketing","Development"]).execute()
print(refined.transformed_content)

输出结果:

Lost in the middle 长上下文精度处理问题

如何处理长文本切分信息丢失?

LangChain解决方案: 先将文本碎片化, 然后根据问题将最相关的切分块放在头尾的位置, 这样回答的问题精度会比较高

安装长文本转换器:

! pip install sentence-transformers

长文本分块

from langchain.chains import LLMChain,StuffDocumentsChain
from langchain.document_transformers import (LongContextReorder
)
from langchain.embeddings import HuggingFaceBgeEmbeddings
from langchain.vectorstores import  Chroma#使用huggingface托管的开源LLM来做嵌入,MiniLM-L6-v2是一个较小的LLM 
embedings = HuggingFaceBgeEmbeddings(model_name="all-MiniLM-L6-v2")text = ["篮球是一项伟大的运动。","带我飞往月球是我最喜欢的歌曲之一。","凯尔特人队是我最喜欢的球队。","这是一篇关于波士顿凯尔特人的文件。","我非常喜欢去看电影。","波士顿凯尔特人队以20分的优势赢得了比赛。","这只是一段随机的文字。","《艾尔登之环》是过去15年最好的游戏之一。","L.科内特是凯尔特人队最好的球员之一。","拉里.伯德是一位标志性的NBA球员。"
]retrieval = Chroma.from_texts(text,embedings).as_retriever(search_kwargs={"k": 10}
)
query = "关于我的喜好都知道什么?"#根据相关性返回文本块
docs = retrieval.get_relevant_documents(query)
docs

输出结果:

根据相关性进行重排

#对检索结果进行重新排序,根据论文的方案
#问题相关性越低的内容块放在中间
#问题相关性越高的内容块放在头尾reordering = LongContextReorder()
reo_docs = reordering.transform_documents(docs)#头尾共有4个高相关性内容块
reo_docs

检测精度效果

from dotenv import load_dotenv
load_dotenv("openai.env")
import osapi_key = os.environ.get("OPENAI_API_KEY")
api_base = os.environ.get("OPENAI_API_BASE")#检测下这种方案的精度效果
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI#设置llm
llm = OpenAI(api_key=api_key,api_base=api_base,model="gpt-3.5-turbo-instruct",temperature=0
)document_prompt = PromptTemplate(input_variables=["page_content"],template="{page_content}"
)stuff_prompt_override ="""Given this text extracts:
----------------------------------------
{context}
----------------------------------------
Please answer the following questions:
{query}
"""prompt = PromptTemplate(template=stuff_prompt_override,input_variables=["context","query"]
)llm_chain = LLMChain(llm=llm,prompt=prompt
)WorkChain = StuffDocumentsChain(llm_chain=llm_chain,document_prompt=document_prompt,document_variable_name="context"
)#调用
WorkChain.run(input_documents=reo_docs,query="我最喜欢做什么事情?"
)

文本向量化实现方式

文本向量化: 一种更高效的检索方式

例如: 向量坐标离的越近越容易一起被搜到, 例如搜索宠物, 那么猫和狗都会被搜索到

引入需要的包

! pip install --upgrade langchain
! pip install --upgrade openai==0.27.8
! pip install -U langchain-openai

查看是否安装完成:

! pip show openai
! pip show langchain
! pip show langchain-openai

测试文本向量化:

from langchain_openai import OpenAIEmbeddingse_model = OpenAIEmbeddings()
ebeddings = e_model.embed_documents(["你好","你好啊","你叫什么名字?","我叫王大锤","很高兴认识你大锤",]
)
ebeddings

测试向量检索:

embedded_query = e_model.embed_query("这段对话中提到了什么名字?")
embedded_query[:5]

嵌入向量缓存

设置缓存到cache目录下

from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import  LocalFileStore
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
u_embeddings = OpenAIEmbeddings()
fs = LocalFileStore("./cache/")
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(u_embeddings,fs,namespace=u_embeddings.model,
)
list(fs.yield_keys())

加载文档, 向量化存入cache缓存中:

#加载文档,切分文档,将切分文档向量化病存储在缓存中raw_documents = TextLoader("letter.txt").load()
text_splitter = CharacterTextSplitter(chunk_size=600,chunk_overlap=0)
documents = text_splitter.split_documents(raw_documents)

安装faiss包, 主要用于向量算法:

! pip install faiss-cup

大概花费多少时间写入了缓存:

from langchain.vectorstores import  FAISS
%timeit -r  1 -n 1 db= FAISS.from_documents(documents,cached_embeddings)

#查看缓存中的键
list(fs.yield_keys())

ChatDoc: 一个文档检索助手

实现

  • 可以加载PDF或者xsl格式文档
  • 可以对文档进行适当切分
  • 使用openai进行向量化
  • 使用Chomadb实现本地向量存储
  • 使用智能检索实现和文档的对话

安装必要的包

#安装必须的包
! pip install wheel
! pip install docx2txt
! pip install pypdf
! pip install nltk
! pip install unstructured

测试加载文档

  • Docx:
#倒入必须的包
from langchain.document_loaders import Docx2txtLoader#定义chatdoc
class ChatDoc():def getFile():#读取文件loader = Docx2txtLoader("example/fake.docx")text = loader.load()return text;ChatDoc.getFile()

  • pdf:
#导入必须的包
from langchain.document_loaders import PyPDFLoader#定义chatdoc
class ChatDoc():def getFile():try:#读取文件loader = PyPDFLoader("example/fake.pdf")text = loader.load()return text;except Exception as e:print(f"Error loading files:{e}")
ChatDoc.getFile()

  • excel:
#导入必须的包
from langchain.document_loaders import UnstructuredExcelLoader#定义chatdoc
class ChatDoc():def getFile():try:#读取文件loader = UnstructuredExcelLoader("example/fake.xlsx",mode="elements")text = loader.load()return text;except Exception as e:print(f"Error loading files:{e}")
ChatDoc.getFile() 

  • 整合优化
#导入必须的包
from langchain.document_loaders import UnstructuredExcelLoader,Docx2txtLoader,PyPDFLoader
from langchain.text_splitter import  CharacterTextSplitter#定义chatdoc
class ChatDoc():def __init__(self):self.doc = Noneself.splitText = [] #分割后的文本def getFile(self):doc = self.docloaders = {"docx":Docx2txtLoader,"pdf":PyPDFLoader,"xlsx":UnstructuredExcelLoader,}file_extension = doc.split(".")[-1]loader_class = loaders.get(file_extension)if loader_class:try:loader = loader_class(doc)text = loader.load()return textexcept Exception as e: print(f"Error loading {file_extension} files:{e}") else:print(f"Unsupported file extension: {file_extension}")return  None #处理文档的函数def splitSentences(self):full_text = self.getFile() #获取文档内容if full_text != None:#对文档进行分割text_split = CharacterTextSplitter(chunk_size=150,chunk_overlap=20,)texts = text_split.split_documents(full_text)self.splitText = textschat_doc = ChatDoc()
chat_doc.doc = "example/fake.xlsx"
chat_doc.splitSentences()
print(chat_doc.splitText)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识C++ · 模拟实现stack和Queue

目录 前言: 1 Stack 1.1 双端队列 2 Queue 前言: 经历了list三个自定义类型的洗礼,来个简单的放松放松,即栈和队列: 文档记录的,栈和队列是一种容器适配器,它们不属于stl,但是它…

平板显示LED背光芯片OC6700,输入3.6V~60V,升压型 LED 恒流驱动器

概述 OC6700是一款内置60V功率NMOS高效率、高精度的升压型大功率LED恒流驱动芯片。OC6700采用固定关断时间的控制方式,关断时间可通过外部电容进行调节,工作频率可根据用户要求而改变。OC6700通过调节外置的电流采样电阻,能控制高亮度LED灯的…

LangChain v0.2介绍

LangChain v0.2介绍 LangSmith:一个开发者平台,可调试、测试、评估和监控LLM应用程序。 LangServe:用于将 LangChain 链部署为 REST API 的包。可以轻松启动并运行生产就绪的 API。 LangChain:包含构成认知架构的链、代理和检索策…

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别 一、香橙派简介1.1、香橙派 AI Pro 硬件资源介绍1.2、华为昇腾310(Ascend310) 简介1.3、 昇腾310AI能力和CANN 简介昇腾310 NPU简介 二、远程环境配置2.1、ssh2.2、vnc…

springboot管理的各依赖版本查看

找一个springboot相关的依赖,比如这里我找mybatis 鼠标点击artifactId名称,图中蓝色字段,跳转到springboot依赖(鼠标悬停在上面变成蓝色表示可点击跳转), 点击spring-boot-dependencites,跳转到…

list(二)和_stack_queue

嗨喽大家好,时隔许久阿鑫又给大家带来了新的博客,list的模拟实现(二)以及_stack_queue,下面让我们开始今天的学习吧! list(二)和_stack_queue 1.list的构造函数 2.设计模式之适配器和迭代器 3.新容器de…

产品人生(9):从“波士顿矩阵”看“个人职业规划”

波士顿矩阵(简称BCG矩阵)是一种战略规划工具,由波士顿咨询公司的创始人布鲁斯亨德森(Bruce Henderson)于1970年代初提出的,它以两个关键指标作为分析维度:市场增长率和相对市场份额,…

k8s牛客面经篇

k8s的pod版块: k8s的网络版块: k8s的deployment版块: k8s的service版块: k8s的探针板块: k8s的控制调度板块: k8s的日志监控板块: k8s的流量转发板块: k8s的宏观版块:

【InternLM实战营第二期笔记】04:XTuner 微调 LLM:1.8B、多模态、Agent

文章目录 笔记微调基础知识Xtuner8G显存微调模型InternLM2 1.8B多模态实践环节数据微调过拟合WebUI 交互 多模态微调 作业 这回学乖了,打开本节课第一件事先不看教程而是装环境~ 笔记 微调基础知识 这里感慨一下,垂直领域的训练还是挺困难的,…

docker安装redis以及持久化

为了避免当虚拟机关机后redis数据丢失的情况,redis需要持久化。所以要挂载数据卷 创建数据和配置存放的目录 [root192 data]# pwd /root/data [root192 data]# mkdir -p /root/data/redis/conf && chmod 777 /root/data/redis/conf [root192 data]# mkdir …

php反序列化中的pop链

目录 一、什么是POP 二、成员属性赋值对象 例题: 方法一 方法二 三、魔术方法的触发规则 例题: 四、POC的编写 例题1: 例题2 [NISACTF 2022]babyserialize 今日总结: 一、什么是POP 在反序列化中,我们…

项目资源管理

目录 1.概述 2.六个过程 2.1. 规划资源管理 2.2. 估算活动资源 2.3. 获取资源 2.4. 建设团队 2.5. 管理团队 2.6. 控制资源 3.应用场景 3.1.十个应用场景 3.2.软件开发项目 3.2.1. 资源规划 3.2.2. 资源分配 3.2.3. 资源获取 3.2.4. 资源优化 3.2.5. 资源监控与…

【AI基础】第二步:安装AI运行环境

开局一张图: 接下来按照从下往上的顺序来安装部署。 规则1 注意每个层级的安装版本,上层的版本由下层版本决定 比如CUDA的版本,需要看显卡安装了什么版本的驱动,然后CUDA的版本不能高于这个驱动的版本。 这个比较好理解&#xff…

ES 生命周期管理

一 .概念 ILM定义了四个生命周期阶段:Hot:正在积极地更新和查询索引。Warm:不再更新索引,但仍在查询。cold:不再更新索引,很少查询。信息仍然需要可搜索,但是如果这些查询速度较慢也可以。Dele…

Java面试——中间件

OpenFeign 1、openFeign是一个HTTP客户端,它融合了springmvc的注解,使之可以用REST风格的映射来请求转发。 2、可以把openFegin理解为是controller层或是service层。可以取代springmvc控制层作为请求映射,亦或是作为service层处理逻辑&#…

C++ priority_queue简单源码剖析:priority_queue模拟实现

文章目录 1. priority_queue介绍2. priority_queue模拟实现3. 适配器与虚函数 大家好!本文会用C模拟一个基本的priority_queue类,帮助我们更好的理解priority_queue的内置函数的实现与规则。 1. priority_queue介绍 priority_queue被叫做优先队列&#…

ESP使用巴法云远程OTA(VScode + Platform io)

ESP使用巴法云远程OTA(Platform) 什么是OTA: OTA(Over-the-AirTechnology)即空中下载技术,是通过移动通信的空中接口实现对移动终端设备及SIM卡数据进行远程管理的技术。OTA升级是物联网(IOT&am…

【C++初阶学习】第十二弹——stack和queue的介绍和使用

C语言栈:数据结构——栈(C语言版)-CSDN博客 C语言队列:数据结构——队列(C语言版)-CSDN博客 前言: 在之前学习C语言的时候,我们已经学习过栈与队列,并学习过如何使用C语言来实现栈与队列&…

企业软件产品和服务 之 设计保证安全 七项承诺

1. 引言 公司如何保护自己免受数据泄露的影响?标准答案就是: “启用多因素身份验证”——MTA(Enable multifactor authentication)。 但是,目前很多公司仍然盲目地只使用密码作为唯一的身份来源。 网络安全的核心是…

深入了解 C 语言 Bug

目录 一、引言二、Bug的定义三、Bug的由来四、Bug的影响五、应对 Bug 的方法六、结论 一、引言 1、在 C 语言的编程世界中,Bug 是一个我们无法回避的话题。 2、Bug,简单来说,就是程序中存在的错误或缺陷。它可以表现为程序运行结果的异常、崩…