【LangChain】Chapter10 - Retrieval

说在前面

上一节,我们介绍了语义搜索的基础知识,并做了一些实践案例,可以看到在有些情况下效果不错,但同时也能看到存在一些边缘情况。本节将介绍 检索(Retrieval)以及讲解一些解决这些边缘案例的高级方法。(视频时长11:48)

Main Content

检索(Retrieval)是检索增强生成(Retrieval Augmented Generation,RAG)的核心,指根据用户的问题去向量数据库中搜索与问题相关的文档内容。当我们访问和查询向量数据库时可能会运用到以下技术:

  • 基本语义相似度(Basic semantic similarity)
  • 最大边际相关性(Maximum marginal relevance,MMR)
  • 过滤元数据
  • LLM辅助检索

本节将介绍几种检索方法,以及解决前述’Failure modes‘的技巧。

在这里插入图片描述

前置工作

1.导入环境变量和 OPENAI API

import os
import openai
import sys
sys.path.append('../..')

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file

openai.api_key  = os.environ['OPENAI_API_KEY']

Vectorstore retrieval

Similarity Search

1.导入 Chroma 和 OpenAIEmbeddings,并做好初始化,文件内容使用的是上一节存储在 'docs/chroma/' 中的讲义数据。

from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
persist_directory = 'docs/chroma/'
embedding = OpenAIEmbeddings()
vectordb = Chroma(
    persist_directory=persist_directory,
    embedding_function=embedding
)

2.向量存储中一共有 209 个内容。

print(vectordb._collection.count())

在这里插入图片描述

3.下面设定 texts,并将其进行向量存储到 smalldb 中。用来做该部分的演示。

texts = [
    """The Amanita phalloides has a large and imposing epigeous (aboveground) fruiting body (basidiocarp).""",
    """A mushroom with a large fruiting body is the Amanita phalloides. Some varieties are all-white.""",
    """A. phalloides, a.k.a Death Cap, is one of the most poisonous of all known mushrooms.""",
]
smalldb = Chroma.from_texts(texts, embedding=embedding)

4.设定问题。

question = "Tell me about all-white mushrooms with large fruiting bodies"

5.在 samllbd 中做语义相似查询,k 设定为 2 返回两条相似度最高的 chunk。

smalldb.similarity_search(question, k=2)

在这里插入图片描述

我们可以看到,相似性搜索 similarity_search 返回两个文档,是texts的第一句和第二句。它们都与用户问题有关,且含义非常相近,其实只返回其中一句足以满足要求。

Addressing Diversity: Maximum marginal relevance

smallbd 中做最大边际相关搜索 MMR,设定返回的 chunk 数为 k=2

smalldb.max_marginal_relevance_search(question,k=2, fetch_k=3)

在这里插入图片描述

最大边际相关(Maximum Marginal Relevance)是实现多样性检索的常用算法。

MMR的介绍

MMR会平衡结果的相关性(relevance)和多样性(diversity),以避免返回内容冗余的结果。
LangChain 的 max_marginal_relevance_search 函数使用MMR算法初步检索 fetch_k 个文档,选择前k个返回。
在这里插入图片描述

下面是一个MMR与SS(语义相似度搜索)的效果对比。

question = "what did they say about matlab?"
docs_ss = vectordb.similarity_search(question,k=3)
docs_ss[0].page_content[:100]

在这里插入图片描述

docs_ss[1].page_content[:100]

在这里插入图片描述

docs_mmr = vectordb.max_marginal_relevance_search(question,k=3)
docs_mmr[0].page_content[:100]

在这里插入图片描述

docs_mmr[1].page_content[:100]

在这里插入图片描述

Addressing Specificity: working with metadata

上一节的 Failure modes中要求只在Lecture03中搜索答案,但是结果中额外包含 Lecture01 和Lecture02 的内容。我们可以通过过滤元数据(metadata)的方式实现精准搜索,从而解决这个问题。

1.设定问题,要求查找 Lecture03 中的内容。

question = "what did they say about regression in the third lecture?"

2.初始化语义相似度搜索,添加过滤器 filter 设定对 metadata 进行过滤,要求只能来源只能是 Lecture03。

docs = vectordb.similarity_search(
    question,
    k=3,
    filter={"source":"docs/cs229_lectures/MachineLearning-Lecture03.pdf"}
)

3.打印查找到的文档可以看到过滤后,就都来自 Lecture03。

for d in docs:
    print(d.metadata)

在这里插入图片描述

Addressing Specificity: working with metadata using self-query retriever

上面的 filter 中的过滤条件是手动设置的,有没有方法可以准确识别问题中的语义从而实现元数据自动过滤呢?LangChain提供 SelfQueryRetriever 解决这个问题,它使用LLM提取query 和 filter。

1.导入 SelfQueryRetriever

from langchain.llms import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo

2.定义元数据过滤条件。metadata_field_info 参数用于描述元数据中的字段及其类型和含义。这个参数的设置对检索器如何解析查询并匹配元数据非常关键。根据 metadata_field_info 信息,LLM会自动从用户问题中提取 query 和 filter,然后向量数据库基于这两项去搜索相关内容。

metadata_field_info = [
    AttributeInfo(
        name="source",
        description="The lecture the chunk is from, should be one of `docs/cs229_lectures/MachineLearning-Lecture01.pdf`, `docs/cs229_lectures/MachineLearning-Lecture02.pdf`, or `docs/cs229_lectures/MachineLearning-Lecture03.pdf`",
        type="string",
    ),
    AttributeInfo(
        name="page",
        description="The page from the lecture",
        type="integer",
    ),
]

document_content_description = "Lecture notes"
llm = OpenAI(model='gpt-3.5-turbo-instruct', temperature=0)
retriever = SelfQueryRetriever.from_llm(
    llm,
    vectordb,
    document_content_description,
    metadata_field_info,
    verbose=True
)

3.LLM提取 query 和filter,query=‘regression’ 来自用户问题,filter是 LLM 根据 metadata_field_info和用户问题设定的过滤条件。

question = "what did they say about regression in the third lecture?"
docs = retriever.get_relevant_documents(question)

在这里插入图片描述

4.可以看到成功的按照我们的要求进行了查找。

for d in docs:
    print(d.metadata)

在这里插入图片描述

Additional tricks: compression

另一种提高检索文档质量的方法是压缩。向量数据库会返回与问题相关的 chunk 中的所有内容,其中包含大量不相关的信息。LangChain提供 ContextualCompressionRetriever 对返回的完整chunk进行压缩,提取与用户问题相关的内容。可以有效提升输出质量,减少计算资源的浪费。

在这里插入图片描述

1.导入 ContextualCompressionRetrieverLLMChainExtractor

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
def pretty_print_docs(docs):
    print(f"\n{'-' * 100}\n".join([f"Document {i+1}:\n\n" + d.page_content for i, d in enumerate(docs)]))

3.设定压缩器。

# Wrap our vectorstore
llm = OpenAI(temperature=0, model="gpt-3.5-turbo-instruct")
compressor = LLMChainExtractor.from_llm(llm)

4.进行压缩并打印。

compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=vectordb.as_retriever()
)
question = "what did they say about matlab?"
compressed_docs = compression_retriever.get_relevant_documents(question)
pretty_print_docs(compressed_docs)

在这里插入图片描述

我们定义了压缩器LLMChainExtractor,负责从向量数据库返回的chunk中提取信息。ContextualCompressionRetriever有两个参数,一个是压缩器LLMChainExtractor实例,另一个是vectordb检索器。

Combining various techniques

这里我们把上面的几种方法结合一下(Compression + metadata)

compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=vectordb.as_retriever(search_type = "mmr")
)
question = "what did they say about matlab?"
compressed_docs = compression_retriever.get_relevant_documents(question)
pretty_print_docs(compressed_docs)

Other types of retrieval

vectordb并不是LangChain唯一的检索器,LangChain还提供了其他检索文档的方式,例如TF-IDF、SVM。

from langchain.retrievers import SVMRetriever
from langchain.retrievers import TFIDFRetriever
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# Load PDF
loader = PyPDFLoader("docs/cs229_lectures/MachineLearning-Lecture01.pdf")
pages = loader.load()
all_page_text=[p.page_content for p in pages]
joined_page_text=" ".join(all_page_text)

# Split9
text_splitter = RecursiveCharacterTextSplitter(chunk_size = 1500,chunk_overlap = 150)
splits = text_splitter.split_text(joined_page_text)
# Retrieve
svm_retriever = SVMRetriever.from_texts(splits,embedding)
tfidf_retriever = TFIDFRetriever.from_texts(splits)
question = "What are major topics for this class?"
docs_svm=svm_retriever.get_relevant_documents(question)
docs_svm[0]

在这里插入图片描述

question = "what did they say about matlab?"
docs_tfidf=tfidf_retriever.get_relevant_documents(question)
docs_tfidf[0]

在这里插入图片描述

总结

本节介绍了关于 Retrieval 的内容。这部分的内容也是现在的 RAG 方向比较新的和充满挑战的方向,学习这部分可以多去阅读最新的文献去了解技术的动向。

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

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

相关文章

【物联网】ARM核介绍

文章目录 一、芯片产业链1. CPU核(1)ARM(2)MIPS(3)PowerPc(4)Intel(5)RISC-V 2. SOC芯片(1)主流厂家(2)产品解决方案 3. 产品 二、ARM核发展1. 不同架构的特点分析(1)VFP(2)Jazelle(3)Thumb(4)TrustZone(5)SIMD(6)NEON 三、ARM核(ARMv7)工作模式1. 权限级别(privilege level)2.…

【深度学习】关键技术-损失函数(Loss Function)

损失函数(Loss Function) 是机器学习和深度学习模型训练过程中的核心概念,用于度量模型的预测输出与真实标签之间的差异。通过最小化损失函数的值,模型可以逐步优化其参数,提高预测性能。 损失函数的作用 衡量模型性能…

软件测试 —— Postman(2)

软件测试 —— Postman(2) GETURL结构协议与主机名路径查询字符串(Query String) 总结 urlcode和urldecodeParams 参数Authorization基本结构常见的认证方案1. Basic 认证2. Bearer Token (OAuth 2.0)3. API 密钥4. 其他认证方案 …

靠右行驶数学建模分析(2014MCM美赛A题)

笔记 题目 要求分析: 比较规则的性能,分为light和heavy两种情况,性能指的是 a.流量与安全 b. 速度限制等分析左侧驾驶分析智能系统 论文 参考论文 两类规则分析 靠右行驶(第一条)2. 无限制(去掉了第一条…

算法日记6.StarryCoding P52:我们都需要0(异或)

一、题目 二、题解: 1、对于这道题,题意为让我们寻找一个数x使得 b[i]a[i]^x, 并且b[1]^b[2]^b[3]^ b[4]^b[5]....0 2、我们把b[i]给拆开,可以得到 3、又因为^满足结合律,因此,可以把括号给拆开 4、接着…

快速入门:如何注册并使用GPT

文章目录 ProtonMail邮箱步骤 1:访问Proton官网步骤 2:创建ProtonMail账户步骤 3:选择注册免费账户步骤 4:填写邮箱地址和手机号(可选)步骤 5:邮箱验证(必须进行验证)步骤…

嵌入式硬件篇---PID控制

文章目录 前言第一部分:连续PID1.比例(Proportional,P)控制2.积分(Integral,I)控制3.微分(Derivative,D)控制4.PID的工作原理5..实质6.分析7.各种PID控制器P控…

将IDLE里面python环境pyqt5配置的vscode

首先安装pyqt5全套:pip install pyqt5-tools 打开Vscode: 安装第三方扩展:PYQT Integration 成功配置designer.exe的路径【个人安装pyqt5的执行路径】,便可直接打开UI文件,进行编辑。 配置pyuic,如果下图填写方法使用…

LDD3学习9--数据类型和定时器

这部分对应的是第七章和第十一章,因为内容也不是很多,就一起写了。里面的内容基本上就是一个个的点,所以也就一个个点简单总结一下。 1 数据类型 1.1 数据长度 不同操作系统类型长度可能不一样,看图的话最好用u8,u16&…

python http server运行Angular 单页面路由时重定向,解决404问题

问题 当Angular在本地ng server运行时候,可以顺利访问各级路由。 但是运行ng build后,在dist 路径下的打包好的额index.html 必须要在服务器下运行才能加载。 在服务器下我们第一次访问路由页面时是没有问题的,但是尝试刷新页面或手动输入路…

SparkSQL数据源与数据存储

文章目录 1. 大数据分析流程2. Spark SQL数据源2.1 SparkSQL常见数据源2.2 SparkSQL支持的文本格式2.3 加载外部数据源步骤 3. 本地文件系统加载数据3.1 本地文件系统加载JSON格式数据3.1.1 概述3.1.2 案例演示 3.2 本地文件系统加载CSV格式数据3.2.1 概述3.2.2 案例演示 3.3 本…

LLM - 大模型 ScallingLaws 的 CLM 和 MLM 中不同系数(PLM) 教程(2)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145188660 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Scalin…

AI agent 在 6G 网络应用,无人机群控场景

AI agent 在 6G 网络应用,无人机群控场景 随着 6G 时代的临近,融合人工智能成为关键趋势。借鉴 IT 行业 AI Agent 应用范式,提出 6G AI Agent 技术框架,包含多模型融合、定制化 Agent 和插件式环境交互理念,构建了涵盖四层结构的框架。通过各层协同实现自主环境感知等能力…

信息奥赛一本通 1168:大整数加法

这道题是一道大整数加法,涉及到高精度的算法,比如说有两个数要进行相加,1111111111111111111111111111111111111112222222222222222222222222222222,那么如果这两个数很大的话我们常用的数据类型是不能进行计算的,那么…

基于YOLOv4与Tkinter的口罩识别系统

往期精彩 基于YOLOv11的番茄成熟度实时检测系统设计与实现 用YOLOv11检测美国手语:挥动手腕的科技魔法 基于YOLOv11模型PyQt的实时鸡行为检测系统研究 OpenCV与YOLO在人脸识别中的应用研究(论文源码) 计算机视觉:农作物病虫害检测系统:基于Y…

机器学习:监督学习与非监督学习

监督学习是利用带有标签的数据进行训练,模型通过学习输入和输出之间的关系来进行预测。也就是说,数据集中既有输入特征,也有对应的输出标签,模型的目标是找到从输入到输出的映射关系。 而无监督学习则使用没有标签的数据进行训练,模型的任务是发现数据中的内在结构或模式…

【unity进阶篇】不同Unity版本对应的C# 版本和API 兼容级别(Api Compatibility Level)选择

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、…

H3CNE-13-静态路由(二)

1.路由优先级 路由类型DirectOSPFStaticRIP管理距离01060100 2.路由度量 配置示例: 配置接口IP、静态路由(去包、回包) 3.静态路由之路由备份 RTB: ip route-static 192.168.1.0 24 10.0.12.1 ip route-ststic 192.168.1.0 24 20.0.12.1 …

【数据分享】1929-2024年全球站点的逐年平均气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,其中又以气温指标最为常用!说到气温数据,最详细的气温数据是具体到气象监测站点的气温数据!本次我们为大家带来的就是具体到气象监…

[Qualcomm]Qualcomm MDM9607 SDK代码下载操作说明

登录Qualcomm CreatePoing Qualcomm CreatePointhttps://createpoint.qti.qua