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

news2024/11/15 21:37:13

文章目录

  • 前言
  • 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 os

from 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 VectorStore


class SelfQuerying:

    def __init__(self):
        # 我们需要同时开通 DASHSCOPE_API_KEY 和 DASHVECTOR_API_KEY
        os.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 name
        vectorstore = DashVector.from_documents(docs, DashScopeEmbeddings(), collection_name="langchain")
        return vectorstore

    def 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 retriever

    def handle_query(self, query: str):
        """
        返回优化查询后的检索结果
        :param query:
        :return:
        """
        # 使用 LLM 优化查询向量,构造优化后的检索
        retriever = self.build_querying_retriever(self.handle_embeddings())
        response = retriever.invoke(query)
        return response

if __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.coloradmin.cn/o/1928622.html

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

相关文章

css - - - - - 去除图片默认的白色背景(混合模式 mix-blend-mode)

去除图片默认的白色背景&#xff08;mix-blend-mode&#xff09; 1. 需求描述2. 原图展示3. 原代码展示4. 使用混合模式(mix-blend-mode)5.修改后效果 1. 需求描述 图片含有白色地图&#xff0c;想要将其去掉 2. 原图展示 3. 原代码展示 <div><img src*****/> &…

基于高德地图实现Android定位功能实现(二)

基于高德地图实现Android定位功能实现&#xff08;二&#xff09; 在实现的高德地图的基本显示后&#xff0c;我们需要不断完善地图的功能 地图界面设计&#xff08;悬浮按钮等&#xff09; 首先就是地图页面的布局&#xff0c;这个根据大家的实际需求进行设计即可&#xff…

无人机图像目标检测

本仓库是人工智能课程的课程作业仓库&#xff0c;主要是完成无人机图像目标检测的任务&#xff0c;我们对visdrone数据集进行了处理&#xff0c;在yolo和ssd两种框架下进行了训练和测试&#xff0c;并编写demo用于实时的无人机图像目标检测。 requirements依赖&#xff1a; ss…

数据结构之‘串’

目录 一. 串的定义二. 串的基本操作三. 串的存储结构3.1 顺序存储3.2 链式存储3.3 基于顺序存储的基本操作 \quad 一. 串的定义 \quad \quad \quad \quad 二. 串的基本操作 \quad \quad 三. 串的存储结构 \quad \quad 3.1 顺序存储 \quad 得一个一个遍历 结合方案一和方案二的优…

[React 进阶系列] useSyncExternalStore hook

[React 进阶系列] useSyncExternalStore hook 前情提要&#xff0c;包括 yup 的实现在这里&#xff1a;yup 基础使用以及 jest 测试 简单的提一下&#xff0c;需要实现的功能是&#xff1a; yup schema 需要访问外部的 storage外部的 storage 是可变的React 内部也需要访问同…

SpringBoot整合阿里云RocketMQ对接,商业版

1.需要阿里云开通商业版RocketMQ 普通消息新建普通主题,普通组,延迟消息新建延迟消息主题,延迟消息组 2.结构目录 3.引入依赖 <!--阿里云RocketMq整合--><dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</…

【C language】扫雷

目录 1.概要2.实现核心思想3.实现过程3.1游戏框架3.2游戏逻辑初始化棋盘 MineInit打印棋盘 MinePrint设置雷 SetMines扫雷 ClearMines 4.总结 1.概要 为了提高C初学者对C语言基本语法的掌控能力&#xff0c;一个极简版的扫雷游戏是十分适合锻炼代码能力的。下面分享仅用数组、…

14_Shell重定向输入输出

14_Shell重定向输入输出 输出重定向&#xff1a;一般情况&#xff0c;输出是在终端直接显示&#xff0c;改变输出位置&#xff0c;改变到文件中&#xff0c;这就是输出重定向 输入重定向&#xff1a;一般情况&#xff0c;输入是读取用户终端输入&#xff0c;改变输入位置&#…

026-GeoGebra中级篇-曲线(2)_极坐标曲线、参数化曲面、分段函数曲线、分形曲线、复数平面上的曲线、随机曲线、非线性动力系统的轨迹

除了参数曲线、隐式曲线和显式曲线之外&#xff0c;还有其他类型的曲线表示方法。本篇主要概述一下极坐标曲线、参数化曲面、分段函数曲线、分形曲线、复数平面上的曲线、随机曲线、和非线性动力系统的轨迹&#xff0c;可能没有那么深&#xff0c;可以先了解下。 目录 1. 极坐…

VScode:前端项目中yarn包的安装和使用

一、首先打开PowerShell-管理员身份运行ISE 输入命令&#xff1a; set-ExecutionPolicy RemoteSigned 选择“全是”&#xff0c;表示允许在本地计算机上运行由本地用户创建的脚本&#xff0c;没有报错就行了 二、接着打开VScode集成终端 输入 npm install -g yarn 再次输入以下…

IoT数据采集网关在企业应用中扮演的角色-天拓四方

随着物联网&#xff08;IoT&#xff09;技术的不断发展&#xff0c;越来越多的企业开始利用IoT技术实现智能化、自动化的生产和管理。在这个过程中&#xff0c;Iot数据采集网关作为连接物理世界与数字世界的桥梁&#xff0c;发挥着至关重要的作用。 IoT数据采集网关是一种硬件…

4.定时器

原理 时钟源&#xff1a;定时器是内部时钟源&#xff08;晶振&#xff09;&#xff0c;计数器是外部计时长度&#xff1a;对应TH TL计数器初值寄存器(高八位,低八位)对应的中断触发函数 中断源中断处理函数Timer0Timer0_Routine(void) interrupt 1Timer1Timer1_Routine(void) …

c++初阶知识——类和对象(中)

目录 1.类的默认成员函数 2.构造函数 3.析构函数 4.拷贝构造函数 5.运算符重载 5.1 赋值运算符重载 5.2 使用运算符重载等特性实现日期类 6.取地址运算符重载 6.1 const成员函数 6.2 取地址运算符重载 1.类的默认成员函数 默认成员函数就是⽤⼾没有显式实现&#…

网站开发:使用VScode安装yarn包和运行前端项目

一、首先打开PowerShell-管理员身份运行ISE 输入命令&#xff1a; set-ExecutionPolicy RemoteSigned 选择“全是”&#xff0c;表示允许在本地计算机上运行由本地用户创建的脚本&#xff0c;没有报错就行了 二、接着打开VScode集成终端 输入 npm install -g yarn 再次输入以…

防火墙双机热备带宽管理综合实验

拓扑图和要求如下&#xff1a; 之前的步骤可以去到上次的实验 1.步骤一&#xff1a; 首先在FW3防火墙上配置接口IP地址&#xff0c;划分区域 创建心跳线&#xff1a; 下面进行双机热备配置&#xff1a; 步骤二&#xff1a; 先将心跳线连接起来 注意&#xff1a;一定要将心跳…

Django select_related()方法

select_related()的作用 select_related()是Django ORM&#xff08;对象关系映射&#xff09;中的一种查询优化方法&#xff0c;主要用于减少数据库查询次数&#xff0c;提高查询效率。当你在查询一个模型实例时&#xff0c;如果这个实例有ForeignKey关联到其他模型&#xff0…

Hadoop-29 ZooKeeper集群 Watcher机制 工作原理 与 ZK基本命令 测试集群效果 3台公网云服务器

章节内容 上节我们完成了&#xff1a; ZNode的基本介绍ZNode节点类型的介绍事务ID的介绍ZNode实机测试效果 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&#xff…

Python JSON处理:兼容性与高级应用

JSON&#xff08;JavaScript Object Notation&#xff09;作为当前最流行的数据传输格式&#xff0c;在Python中也有多种实现方式。由于JSON的跨平台性和简便易用性&#xff0c;它在数据交互中被广泛应用。本文将重点讨论如何熟练应用Python的JSON库&#xff0c;将JSON数据映射…

【区块链 + 智慧政务】中国铁塔区块链委托代征开票应用 | FISCO BCOS应用案例

中国铁塔是全球规模最大的通信铁塔基础设施服务提供者。通信塔站址点多面广&#xff0c;业主构成复杂&#xff0c;因此产生海量税务、合同、票据等信息。为进一步提高场租或供电取票的及时性和规范性&#xff0c;严格遵循税务相关的要求&#xff0c;中国铁塔采用国产开源联盟链…

python--实验12

目录 知识点 第一部分&#xff1a;文件概述 第二部分&#xff1a;文件的基本操作 第三部分&#xff1a;目录管理 第四部分&#xff1a;CSV文件读写 第五部分&#xff1a;openpyxl等模块 小结 实验 知识点 第一部分&#xff1a;文件概述 文件标识&#xff1a;找到计算机…