LLM-阿里 DashVector + langchain self-querying retriever 优化 RAG 实践【Query 优化】

文章目录

  • 前言
  • self querying 简介
  • 代码实现
  • 总结

前言

现在比较流行的 RAG 检索就是通过大模型 embedding 算法将数据嵌入向量数据库中,然后在将用户的查询向量化,从向量数据库中召回相似性数据,构造成 context template, 放到 LLM 中进行查询。

如果说将用户的查询语句直接转换为向量查询可能并不会得到很好的结果,比如说我们往向量数据库中存入了一些商品向量,现在用户说:“我想要一条价格低于20块的黑色羊毛衫”,如果使用传统的嵌入算法,该查询语句转换为向量查询就可能“失帧”,被转换为查询黑色羊毛衫。

针对这种情况我们就会使用一些优化检索查询语句方式来优化 RAG 查询,其中 langchain 的 self-querying 就是一种很好的方式,这里使用阿里云的 DashVector 向量数据库和 DashScope LLM 来进行尝试,优化后的查询效果还是挺不错的。


现在很多网上的资料都是使用 OpenAI 的 Embedding 和 LLM,但是个人角色现在国内阿里的 LLM 和向量数据库已经非常好了,而且 OpenAI 已经禁用了国内的 API 调用,国内的云服务又便宜又好用,真的不尝试一下么?关于 DashVector 和 DashScope 我之前写了几篇实践篇,大家感兴趣的可以参考下:

LLM-文本分块(langchain)与向量化(阿里云DashVector)存储,嵌入LLM实践
LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结
LLM-langchain 与阿里 DashScop (通义千问大模型) 和 DashVector(向量数据库) 结合使用总结

前提条件

  • 确保开通了通义千问 API key 和 向量检索服务 API KEY
  • 安装依赖:
    pip install langchain
    pip install langchain-community
    pip install dashVector
    pip install dashscope

self querying 简介

简单来说就是通过 self-querying 的方式我们可以将用户的查询语句进行结构化转换,转换为包含两层意思的向量化数据:

  • Query: 和查询语义相近的向量查询
  • Filter: 关于查询内容的一些 metadata 数据

image.png
比如说上图中用户输入:“bar 说了关于 foo 的什么东西?”,self-querying 结构化转换后就变为了两层含义:

  • 查询关于 foo 的数据
  • 其中作者为 bar

代码实现

DASHSCOPE_API_KEY, DASHVECTOR_API_KEY, DASHVECTOR_ENDPOINT替换为自己在阿里云开通的。

import osfrom langchain_core.documents import Document
from langchain_community.vectorstores.dashvector import DashVector
from langchain_community.embeddings.dashscope import DashScopeEmbeddings
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.vectorstores import VectorStoreclass SelfQuerying:def __init__(self):# 我们需要同时开通 DASHSCOPE_API_KEY 和 DASHVECTOR_API_KEYos.environ["DASHSCOPE_API_KEY"] = ""os.environ["DASHVECTOR_API_KEY"] = ""os.environ["DASHVECTOR_ENDPOINT"] = ""self.llm = ChatTongyi(temperature=0)def handle_embeddings(self)->'VectorStore':docs = [Document(page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},),Document(page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2},),Document(page_content="A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",metadata={"year": 2006, "director": "Satoshi Kon", "rating": 8.6},),Document(page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3},),Document(page_content="Toys come alive and have a blast doing so",metadata={"year": 1995, "genre": "animated"},),Document(page_content="Three men walk into the Zone, three men walk out of the Zone",metadata={"year": 1979,"director": "Andrei Tarkovsky","genre": "thriller","rating": 9.9,},),]# 指定向量数据库中的 Collection namevectorstore = DashVector.from_documents(docs, DashScopeEmbeddings(), collection_name="langchain")return vectorstoredef build_querying_retriever(self, vectorstore: 'VectorStore', enable_limit: bool=False)->'SelfQueryRetriever':"""构造优化检索:param vectorstore: 向量数据库:param enable_limit: 是否查询 Top k:return:"""metadata_field_info = [AttributeInfo(name="genre",description="The genre of the movie. One of ['science fiction', 'comedy', 'drama', 'thriller', 'romance', 'action', 'animated']",type="string",),AttributeInfo(name="year",description="The year the movie was released",type="integer",),AttributeInfo(name="director",description="The name of the movie director",type="string",),AttributeInfo(name="rating", description="A 1-10 rating for the movie", type="float"),]document_content_description = "Brief summary of a movie"retriever = SelfQueryRetriever.from_llm(self.llm,vectorstore,document_content_description,metadata_field_info,enable_limit=enable_limit)return retrieverdef handle_query(self, query: str):"""返回优化查询后的检索结果:param query::return:"""# 使用 LLM 优化查询向量,构造优化后的检索retriever = self.build_querying_retriever(self.handle_embeddings())response = retriever.invoke(query)return responseif __name__ == '__main__':q = SelfQuerying()# 只通过查询属性过滤print(q.handle_query("I want to watch a movie rated higher than 8.5"))# 通过查询属性和查询语义内容过滤print(q.handle_query("Has Greta Gerwig directed any movies about women"))# 复杂过滤查询print(q.handle_query("What's a highly rated (above 8.5) science fiction film?"))# 复杂语义和过滤查询print(q.handle_query("What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated"))

上边的代码主要步骤有三步:

  • 执行 embedding, 将带有 metadata 的 Doc 嵌入 DashVector
  • 构造 self-querying retriever,需要预先提供一些关于我们的文档支持的元数据字段的信息以及文档内容的简短描述。
  • 执行查询语句

执行代码输出查询内容如下:

# "I want to watch a movie rated higher than 8.5"
[Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'director': 'Andrei Tarkovsky', 'genre': 'thriller', 'rating': 9.9, 'year': 1979}),Document(page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea', metadata={'director': 'Satoshi Kon', 'rating': 8.6, 'year': 2006})]# "Has Greta Gerwig directed any movies about women"
[Document(page_content='A bunch of normal-sized women are supremely wholesome and some men pine after them', metadata={'director': 'Greta Gerwig', 'rating': 8.3, 'year': 2019})]# "What's a highly rated (above 8.5) science fiction film?"
[Document(page_content='A bunch of normal-sized women are supremely wholesome and some men pine after them', metadata={'director': 'Greta Gerwig', 'rating': 8.3, 'year': 2019})]# "What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated"
[Document(page_content='Toys come alive and have a blast doing so', metadata={'genre': 'animated', 'year': 1995})]

总结

本文主要讲了如何使用 langchain 的 self-query 来优化向量检索,我们使用的是阿里云的 DashVector 和 DashScope LLM 进行的代码演示,读者可以开通下,体验尝试一下。

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

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

相关文章

python如何判断变量是否可迭代

python如何判断变量是否可迭代?方法如下: 方法一: 适用于python2和python3 >>> from collections import Iterable >>> isinstance("str", Iterable) True 方法二: 适用于python3 s "hello …

InterSystems IRIS使用python pyodbc连接 windows环境,odbc驱动安装,DSN配置,数据源配置

一、创建的数据库和数据 SELECT 1SELECT $ZVERSIONCREATE TABLE MyApp.Person ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHAR(1) );CREATE TABLE MyApp.Person2 ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHA…

Gil-Pelaez inversion

一、特征函数 A.随即变量的特征函数定义与性质 B.特征函数与PDF的关系 傅里叶变换:C.特征函数与矩函数关系 二、Gil-Pelaez反演定理 输入功率 P i n P_{in}

MYSQL 四、mysql进阶 9(数据库的设计规范)

一、为什么需要数据库设计 二、范 式 2.1 范式简介 在关系型数据库中,关于数据表设计的基本原则、规则就称为范式。 可以理解为,一张数据表的设计结 构需要满足的某种设计标准的 级别 。要想设计一个结构合理的关系型数据库,必须满足一定的…

13 IP层协议-网际控制报文协议ICMP

计算机网络资料下载:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/140148186 为了更有效的转发IP数据报和提高交付成果的机会,在网际层使用了网际控制报文协议ICMP。ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP不是高层协议数…

Java面试八股之Redis集群Cluster

Redis集群Cluster Redis Cluster是一种基于数据分片(Sharding)的分布式缓存和存储系统,它实现了数据的水平扩展、高可用性和自动故障转移。以下是对Redis Cluster模式详细实现流程的描述: 1. 初始化与配置 部署节点&#xff1a…

C++ //练习 15.15 定义你自己的Disc_quote和Bulk_quote。

C Primer(第5版) 练习 15.15 练习 15.15 定义你自己的Disc_quote和Bulk_quote。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 /******************************************************************…

Python酷库之旅-第三方库Pandas(026)

目录 一、用法精讲 65、pandas.bdate_range函数 65-1、语法 65-2、参数 65-3、功能 65-4、返回值 65-5、说明 65-6、用法 65-6-1、数据准备 65-6-2、代码示例 65-6-3、结果输出 66、pandas.period_range函数 66-1、语法 66-2、参数 66-3、功能 66-4、返回值 6…

Gooxi受邀参加第三届中国数据中心服务器与设备峰会

7月2-3日,第三届中国数据中心服务器与设备峰会在上海召开,作为国内最聚焦在服务器领域的专业峰会,吸引了来自全国的行业专家、服务器与机房设备厂家,企业IT用户,数据中心业主共同探讨AIGC时代下智算中心设备的设计之道…

2024年最新最全面的Apifox使用-自动化测试

正文 编排测试场景运行测试持续集成查看测试结果 编排测试场景 新建测试场景 测试场景用于将多个接口有序地组合在一起运行,用于测试一个完整业务流程。 打开 Apifox 后点击左侧菜单栏中的“自动化测试”,点击左上角 号,选择所归属的目录…

记录|.NET上位机开发和PLC通信的实现

本文记录源自:B站视频 实验结果:跟视频做下来是没有问题的。能运行。 目录 前言一、项目Step1. 创建项目Step2. 创建动态图片展示Step3. 创建图片型按钮Step4. 创建下拉框Step1~4的效果展示Step5. 编程实体类操作类Main函数 Step1~5的效果展示Main函数 最…

Binder框架(二) ServiceManager初始化

0、总体流程四部 开机由init进程解析init.rc文件启动servicemanager.rc。启动会调用main.cpp的main函数 main函数里面主要做了以下几件事 : 1.1 打开/dev/binder设备; 1.2 通过mmap映射设备的内存空间到ServiceManager进程中。 1.3 设置ServiceManager为context…

气象水文耦合模式WRF-Hydro建模、编译及运行流程、依赖库准备、案例实践等

目录 第一部分 WRF-Hydro模型功能及运行流程、依赖库准备 第二部分 WRF-Hydro模式编译、离线运行及案例实践 第三部分 结合多案例进行模式数据制备及实践应用 第四部分 模式耦合编译及运行、总结 更多应用 WRF-Hydro模型是一个分布式水文模型,‌它基于WRF‌陆面…

数据库启动报ORA-600 6711故障分析处理---惜分飞

几个月以前的一个数据库故障,今天拿出来在win上重新分析,数据库启动报ORA-600 6711错 C:\Users\XFF>SQLPLUS / AS SYSDBA SQL*Plus: Release 12.1.0.2.0 Production on 星期日 7月 14 16:17:32 2024 Copyright (c) 1982, 2014, Oracle. All rights reserved. 已连接到空…

LabVIEW扬尘控制系统

设计了一套基于LabVIEW的扬尘控制系统,通过监测TsP(总悬浮颗粒物)浓度、风向和摄像头视频,实现对环境的综合监控和扬尘控制。系统可以自动判断扬尘位置,并驱动抑尘设备进行抑尘。硬件选用NI cDAQ-9178数据采集模块、Om…

linux高级编程(网络)(www,http,URL)

数据的封包和拆包 封包: 应用层数据(例如HTTP请求)被传递给传输层。传输层(TCP)在数据前添加TCP头部(包含端口号、序列号等)。网络层(IP)在TCP段前添加IP头部&#xff…

数据库:基本操作

SQL struct query language 关系型数据库 非关系 芒果db ddl data defination language 建表 dml 新增 修改 删除一行 data modifty dql 查询 data query language 查询 select 数据库 sun solaris gnu 1、分类: 大型 中型 …

Linux FFmpeg安装教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

DHCP服务、FTP服务

一、DHCP 1.1 DHCP是什么 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一种网络协议,用于自动分配 IP 地址和其他网络配置信息给网络中的设备 1.2 DHCP的好处 自动化: 减少了手动配置 IP 地址和网络参数的工…

Vulnhub:DC-1

1.环境搭建 靶机下载地址 将下载的靶机导入到Oracle VM VirtualBox中,设置仅主机模式,使用和kali相同的网卡 2.渗透过程 使用nmap工具进行主机发现扫描 nmap -sn 192.168.56.0/24 发现靶机ip地址,使用nmap工具进行靶机端口扫描 nmap -sS…