langchain从入门到精通(三十二)——RAG优化策略(八)自查询检索器实现动态数据过滤

1. 查询构建与自查询检索器

在 RAG 应用开发中,检索外部数据时,前面的优化案例中,无论是生成的 子查询、问题分解、生成假设性文档,最后在执行检索的时候使用的都是固定的筛选条件(没有附加过滤的相似性搜索)
但是在某些情况下,用户发起的原始提问其实隐式携带了 筛选条件,例如提问:
请帮我整理下关于2023年全年关于AI的新闻汇总。
在这段 原始提问 中,如果执行相应的向量数据库相似性搜索,其实是附加了 筛选条件 的,即 year=2023,但是在普通的相似性搜索中,是不会考虑 2023 年这个条件的(因为没有添加元数据过滤器,2022年和2023年数据在高维空间其实很接近),存在很大概率会将其他年份的数据也检索出来。
那么有没有一种策略,能根据用户传递的 原始问题 构建相应的 元数据过滤器 呢?这样在搜索的时候带上对应的元数据过滤器,不仅可以压缩检索范围,还能提升搜索的准确性。这个思想其实就是 查询构建 或者称为 自查询。
并且除了 向量数据库,类比映射到 关系型数据库、图数据库 也是同样的操作技巧,即:

  1. 关系型数据库自查询:使用 LLM 将自然语言转换成 SQL 过滤语句。
  2. 图数据库自查询:使用 LLM 将自然语言转换成图查询语句。
  3. 向量数据库:使用 LLM 将自然语言转换成元数据过滤器/向量检索器。
    这就是 查询构建 概念的由来,但是并不是所有的数据都支持 查询构建 的,需要看存储的 Document 是否存在元数据,对应的数据库类型是否支持筛选,在 LangChain 中是否针对性做了封装(如果没封装,自行实现难度比较大)。
    在这里插入图片描述
    将 查询构建 这个步骤单独拎出来,它的运行流程其实很简单,但是底层的操作非常麻烦,如下:
    在这里插入图片描述

在 LangChain 中,针对一些高频使用的向量数据库封装了 自查询检索器 的相关支持——SelfQueryRetriever,无需自行构建转换语句与解析,使用该类进行二次包装即可。
所有支持 自查询检索器 的向量数据库都在这个链接内部可以看到使用示例:https://imooc-langchain.shortvar.com/docs/integrations/retrievers/self_query/(但是因为向量数据库的更新频率过快,LangChain 封装的部分向量数据库已经更新,但是 SelfQueryRetriever 内部的逻辑还未更新)。

SelfQueryRetriever 使用起来也非常简单,以 Pinecone 向量数据库为例,首先安装对应的依赖:

pip install --upgrade --quiet lark

定义好 带元数据的文档、支持过滤的元数据、包装的向量数据库、文档内容的描述 等信息,即可进行快速包装,示例代码如下:

import dotenv
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers import SelfQueryRetriever
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_pinecone import PineconeVectorStoredotenv.load_dotenv()# 1.构建文档列表并上传到数据库
documents = [Document(page_content="肖申克的救赎",metadata={"year": 1994, "rating": 9.7, "director": "弗兰克·德拉邦特"},),Document(page_content="霸王别姬",metadata={"year": 1993, "rating": 9.6, "director": "陈凯歌"},),Document(page_content="阿甘正传",metadata={"year": 1994, "rating": 9.5, "director": "罗伯特·泽米吉斯"},),Document(page_content="泰坦尼克号",metadat={"year": 1997, "rating": 9.5, "director": "詹姆斯·卡梅隆"},),Document(page_content="千与千寻",metadat={"year": 2001, "rating": 9.4, "director": "宫崎骏"},),Document(page_content="星际穿越",metadat={"year": 2014, "rating": 9.4, "director": "克里斯托弗·诺兰"},),Document(page_content="忠犬八公的故事",metadat={"year": 2009, "rating": 9.4, "director": "莱塞·霍尔斯道姆"},),Document(page_content="三傻大闹宝莱坞",metadat={"year": 2009, "rating": 9.2, "director": "拉库马·希拉尼"},),Document(page_content="疯狂动物城",metadat={"year": 2016, "rating": 9.2, "director": "拜伦·霍华德"},),Document(page_content="无间道",metadat={"year": 2002, "rating": 9.3, "director": "刘伟强"},),
]
db = PineconeVectorStore(index_name="llmops",embedding=OpenAIEmbeddings(model="text-embedding-3-small"),namespace="dataset",text_key="text"
)
db.add_documents(documents)# 2.创建自查询元数据
metadata_field_info = [AttributeInfo(name="year",description="电影的发布年份",type="integer",),AttributeInfo(name="rating",description="电影的评分",type="float",),AttributeInfo(name="director",description="电影的导演",type="string",),
]# 3.创建子查询检索
self_query_retriever = SelfQueryRetriever.from_llm(llm=ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0),vectorstore=db,document_contents="电影的名字",metadata_field_info=metadata_field_info,enable_limit=True,
)# 4.检索示例
search_docs = self_query_retriever.invoke("查找下评分高于9.5分的电影")print(search_docs)
print(len(search_docs))
输出内容:
[Document(metadata={'director': '陈凯歌', 'rating': 9.6, 'year': 1993.0}, page_content='霸王别姬'), Document(metadata={'director': '弗兰克·德拉邦特', 'rating': 9.7, 'year': 1994.0}, page_content='肖申克的救赎')]

自查询检索器 对于面向特定领域的专用 Agent 效果相对较好(对通用 Agent 来说效果较差),因为这些领域的文档一般相对来说比较规范,例如:财报、新闻、自媒体文章、教培等行业,这些行业的数据都能剥离出通用支持过滤与筛选的 元数据/字段,使用自查询检索器能抽象出对应的检索字段信息。

2 . 自查询检索器的运行逻辑与衍生

在 LangChain 中,涉及调用第三方服务或者调用本地自定义工具的,例如 自查询检索器、检索器逻辑路由 等,在底层都是通过一个预设好的 Prompt 生成符合相应规则的内容(字符串、JSON),然后通过 解析器 解析生成的内容,并将解析出来的结构化内容调用特定的接口、服务亦或者本地函数实现。
例如在 自查询检索器 底层,首先使用 FewShotPromptTemplate+函数回调/结构化输出 生成特定规则的 查询语句,这段提示代码如下:

DEFAULT_SCHEMA = """\
<< Structured Request Schema >>
When responding use a markdown code snippet with a JSON object formatted in the following schema:\```json
{{{{"query": string \\ text string to compare to document contents"filter": string \\ logical condition statement for filtering documents
}}}}
\```The query string should contain only text that is expected to match the contents of documents. Any conditions in the filter should not be mentioned in the query as well.A logical condition statement is composed of one or more comparison and logical operation statements.A comparison statement takes the form: `comp(attr, val)`:
- `comp` ({allowed_comparators}): comparator
- `attr` (string):  name of attribute to apply the comparison to
- `val` (string): is the comparison valueA logical operation statement takes the form `op(statement1, statement2, ...)`:
- `op` ({allowed_operators}): logical operator
- `statement1`, `statement2`, ... (comparison statements or logical operation statements): one or more statements to apply the operation toMake sure that you only use the comparators and logical operators listed above and no others.
Make sure that filters only refer to attributes that exist in the data source.
Make sure that filters only use the attributed names with its function names if there are functions applied on them.
Make sure that filters only use format `YYYY-MM-DD` when handling date data typed values.
Make sure that filters take into account the descriptions of attributes and only make comparisons that are feasible given the type of data being stored.
Make sure that filters are only used as needed. If there are no filters that should be applied return "NO_FILTER" for the filter value.\
"""

原始问题如下:

查找下评分高于9.5分的电影

生成的查询语句原文如下:

{"query": "","filter": "gt(\"rating\", 9.5)"
}

接下来使用特定的转换器,将生成的查询语句转换成适配向量数据库的 过滤器,并在检索时传递该参数,从而完成自查询构建的全过程,不同的向量数据库对应的转换器差异也非常大。
这个思想其实已经涉及到将 LLM 与企业自有应用/API进行快速对接智能化,即如何将 LLM 生成的 文字信息 对接到当前业务系统中。
例如企业自有一套 PPT 生成 API 接口,通过传递设定的参数即可生成对应的 PPT,假设有这样一段参数规则:

[{"page": 1, # PPT的页数"background": {"size": [400, 600],  # 背景图片大小"position": [0, 0],  # 背景图片位置"image_url": "xxx",  # 图片URL...},"objects": [{"type": "title",  # 对象类型"attribute": {"content": "求知若渴,虚心若愚",  # 标题内容"size": 20,  # 标题字体大小"color": "#000000",  # 标题颜色"position": [240, 128],  # 标题位置"font": "微软雅黑",  # 标题字体...}},...],...}
]

如果想通过 LLM 构建一个 PPT 自动生成工具,只需要设定好 prompt,让 LLM 按照特定的规则生成一段用于描述 PPT信息的参数,接下来解析这段参数,并将相应的参数传递给现成没有智能的 PPT 生成工具,即可快速实现 自然语言->PPT 的过程。
当然在这类应用的开发过程中,需要考虑的其他因素其实还非常多,例如:

  1. 大语言模型上下文长度:涉及到的生成内容过多,没法一次性生成,需要确保多次生成参数之间的连贯性。
  2. prompt描述:对于一些复杂的应用,原有参数可能非常复杂,需要通过合适的方式将参数描述添加到 prompt 中。
  3. 生成内容To调用参数:对于生成的内容,有些是字符串的形式(函数回调生成的参数数量是有限制的),如何通过合适方式将字符串无损转换成调用参数。
  4. 参数校验:因为大语言模型输出的随机性,需要对生成的参数进行校验,校验的复杂性。

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

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

相关文章

面向安全产品测试的静态混淆型 Shellcode Loader 设计与对抗分析

github 地址&#xff1a;https://github.com/LilDean17/ShellcodeLoader2025 一、项目背景 近年来&#xff0c;随着 C2 框架广泛应用于安全对抗模拟&#xff0c;各大安全厂商也不断提升其检测能力&#xff0c;那么安全厂商自研的安全软件&#xff0c;是否能有效防御此类威胁&…

深度强化学习DRL——策略学习

一、策略网络 策略函数 π \pi π的输入是状态 s s s和动作 a a a&#xff0c;输出是一个介于0和1之间的概率值&#xff0c;用神经网络 π ( a ∣ s ; θ ) \pi(a \mid s; \boldsymbol{\theta}) π(a∣s;θ)近似策略函数 π ( a ∣ s ) \pi(a\mid s) π(a∣s)&#xff0c; θ …

ISP Pipeline(5): Auto White Balance Gain Control (AWB) 自动白平衡

G_gain 1.0 # 常作为参考通道 R_gain G_avg / R_avg B_gain G_avg / B_avgAuto White Balance Gain Control&#xff08;AWB&#xff09;自动调整图像中红色、绿色、蓝色通道的增益&#xff0c;使图像中灰白区域的颜色看起来为“中性白”或“灰白”&#xff0c;从而矫正因光…

Python中钩子函数的实现方式

在Python中&#xff0c;钩子函数(Hook)是一种允许你在程序执行的特定点插入自定义代码的技术。它本质上是一种回调机制&#xff0c;当特定事件发生时自动调用预先注册的函数。 Python中钩子函数的实现方式 Python中实现钩子主要有以下几种方式&#xff1a; ​回调函数​&…

【RTSP从零实践】3、实现最简单的传输H264的RTSP服务器

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

零开始git使用教程-传html文件

1. 准备工作 (1) 确保你已经安装&#xff1a; Visual Studio (VS)&#xff08;任何版本&#xff0c;社区版也行&#xff09; Git&#xff08;去官网 git-scm.com 下载安装&#xff09; (2) 注册 Gitee/GitHub 账号 国内推荐 Gitee&#xff08;码云&#xff09;&#xff1a;…

CPT204-Advanced OO Programming: Lists, Stacks, Queues, and Priority Queues

目录 1.Java 集合框架层次结构Java Collection Framework hierarchy 1.1Java 集合框架描述&#xff1a; 1.2数据结构Data structures 1.3 Java 集合框架支持两种类型的容器&#xff08;数据结构&#xff09;&#xff1a; 1.4 Java 集合框架的设计 2.Collection 2.1 Coll…

【网络安全】Mysql注入中锁机制

前言 在sql注入的延时注入中&#xff0c;常见的函数有sleep()直接延时、BENCHMARK()通过让数据库进行大量的计算而达到延时的效果、笛卡尔积、正则匹配等&#xff0c;但还有一个常常被忽略的函数&#xff0c;也就是Mysql中的锁机制。虽然早些年就已经出现过相关的技术文章&…

博途多重背景、参数实例

1&#xff1a;我们在博途中先新建一个工程&#xff0c;并且建立一个FB块名字为motor_fb&#xff0c;同样建立一个FC块名字为MOTOR_FC&#xff0c;里面写上我们电机程序里常用的逻辑控制。二者程序内容相同。下面是motor_fb块的程序截图: 2:我们再新建一个FB块&#xff0c;名字为…

运维的利器–监控–zabbix–第三步:配置zabbix–中间件–Tomcat–步骤+验证

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;目前中南大学MBA在读&#xff0c;也考取过HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &…

大模型在重症哮喘手术全流程风险预测与治疗方案制定中的应用研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目标与方法 1.3 研究创新点 二、重症哮喘概述 2.1 定义与发病机制 2.2 分类与临床表现 2.3 诊断标准与方法 三、大模型技术原理与应用现状 3.1 大模型的基本原理 3.2 在医疗领域的应用案例分析 3.3 适用于重症哮喘预测的…

Webpack的插件机制Tapable

Tapable 是一个轻量级的库&#xff0c;用于创建和管理插件钩子&#xff08;hooks&#xff09;&#xff0c;它在 Webpack 中广泛应用&#xff0c;用于实现插件系统。Tapable 提供了一种机制&#xff0c;允许插件在特定的生命周期阶段插入自定义逻辑&#xff0c;从而扩展应用程序…

FRONT归因-两阶段训练流程

FRONT, Fine-Grained Grounded Citations归因 FRONT归因&#xff0c;首先从检索到的源文档中选择支持性引用&#xff0c;然后基于这些引用指导生成过程&#xff0c;确保生成回答有据可依&#xff0c;引用准确无误。 FRONT的特色在于两阶段归因训练&#xff0c;要点如下: 阶…

单端转差分放大器AD8138

根据 AD8138 的数据手册特性及参数&#xff0c;可以实现单端 5Vpp&#xff08;偏置 0V&#xff09;正弦波转差分 5Vpp&#xff08;共模 2.5V&#xff09;的功能&#xff0c;但需注意以下细节&#xff1a; 1. 信号幅度匹配性 输入信号&#xff1a;单端 5Vpp&#xff08;峰峰值…

用R包mice进行多重插补

利用R包mice实现的链式方程多重插补方法来插补缺失的数据。 所有多重插补方法都遵循三个步骤 插补——与单次插补类似&#xff0c;对缺失值进行插补。但是&#xff0c;插补值会从分布中提取m次&#xff0c;而不是仅提取一次。此步骤结束时&#xff0c;应该有m 个完整的数据集…

【专题】网络攻防技术期末复习资料

网络攻防技术期末复习资料 链接&#xff1a;https://blog.csdn.net/Pqf18064375973/article/details/148996272?sharetypeblogdetail&sharerId148996272&sharereferPC&sharesourcePqf18064375973&sharefrommp_from_link 网络安全威胁的成因。 分类&#xff1a…

地震灾害的模拟

为确保地震灾害模拟的准确性和高效性&#xff0c;涉及的系统需要处理复杂的物理模型、数据输入和多层次的模拟过程。在技术设计方案中&#xff0c;我们将涵盖以下几个方面&#xff1a; 背景&#xff1a;描述该模拟系统的目的与应用场景。需求&#xff1a;列出系统的功能需求&a…

9.9 《1/10成本实现GPT-3.5级表现!ChatGLM3-6B QLoRA微调实战:4bit量化+低秩适配全解析》

1/10成本实现GPT-3.5级表现!ChatGLM3-6B QLoRA微调实战:4bit量化+低秩适配全解析 ChatGLM3-6B 微调入门实战:QLoRA 量化低秩适配技术 ▲ ChatGLM3-6B采用GLM架构改进版,支持32K上下文长度和代码生成能力 一、QLoRA 技术原理精要 QLoRA(Quantized Low-Rank Adaptation)…

【Python基础】11 Python深度学习生态系统全景解析:从基础框架到专业应用的技术深度剖析(超长版,附多个代码及结果)

引言:Python在深度学习领域的统治地位 在人工智能浪潮席卷全球的今天,Python已经成为深度学习领域当之无愧的王者语言。这不仅仅是因为Python语法简洁易学,更重要的是围绕Python构建的深度学习生态系统的完整性和强大性。从Google的TensorFlow到Facebook的PyTorch,从科学计…

RESTful API 设计原则深度解析

在 Web 服务架构中&#xff0c;RESTful API作为一种轻量级、可扩展的接口设计风格&#xff0c;通过 HTTP 协议实现资源的标准化访问。本文从核心原则、URL 设计、HTTP 方法应用、状态管理及面试高频问题五个维度&#xff0c;结合工程实践与反例分析&#xff0c;系统解析 RESTfu…