释放你的元数据:使用 Elasticsearch 的自查询检索器

news2025/2/15 18:28:30

作者:来自 Elastic Josh Asres

了解如何使用 Elasticsearch 的 “self-quering” 检索器来通过结构化过滤器提高语义搜索的相关性。

在人工智能搜索的世界中,在海量的数据集中高效地找到正确的数据至关重要。传统的基于关键词的搜索在处理涉及自然语言的查询时往往会失效,这时就需要语义搜索了。然而,如果你想将语义搜索的功能与过滤日期和数字值等结构化元数据的能力结合起来,那么自查询检索器(self-querying retrievers)就可以发挥作用了。

自查询检索器提供了一种强大的方法来利用元数据进行更精确、更细致的搜索。当与 Elasticsearch 的搜索和索引功能相结合时,自查询变得更加强大,使开发人员能够提高 RAG 应用程序的相关性。这篇博文将探讨自查询检索器的概念,展示它们使用 LangChain 和 Python 与 Elasticsearch 的集成,以及它如何帮助你的搜索变得更加强大!

什么是自查询检索器(self-querying Retrievers)?

自查询检索器是 LangChain 提供的一项功能,它弥合了自然语言查询和结构化元数据过滤之间的差距。他们不再仅仅依靠关键字与文档内容的匹配,而是使用大型语言模型 (LLM) 以及 Elasticsearch 的想量搜索功能来解析用户的自然语言查询并智能地提取相关的元数据过滤器。例如,用户可能会问 “Find science fiction movies released after 2000 with a rating above 8 - 查找 2000 年后上映的评分高于 8 的科幻电影”。传统的搜索引擎如果没有关键词就很难找到隐含的含义,而单独的语义搜索可以理解查询的上下文,但无法应用日期和评级过滤器来获得最佳答案。但是,自查询检索器会分析查询,识别元数据字段(类型、年份、评级),并生成 Elasticsearch 可以理解和有效执行的结构化查询。这可以提供更加直观和用户友好的搜索体验,用户可以用简单的英语表达包含过滤器的复杂搜索条件。

所有这些都通过 LLM 链进行,其中 LLM 解析查询以从自然语言查询中提取过滤器,然后将新的结构化过滤器应用于包含 Elasticsearch 中的嵌入和元数据的文档。

Source: Langchain

实现自查询检索器

将自查询检索器与 Elasticsearch 集成涉及几个关键步骤。在我们的 Python 示例中,我们将使用 LangChain 的 AzureChatOpenAI 和 AzureOpenAIEmbeddings 以及 ElasticsearchStore 来管理它。我们首先引入所有 LangChain 库,设置 LLM 以及用于创建向量的嵌入模型:

from langchain_openai import AzureOpenAIEmbeddings, AzureChatOpenAI
from langchain_elasticsearch import ElasticsearchStore
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.docstore.document import Document
import os
llm = AzureChatOpenAI(
   azure_endpoint=os.environ["AZURE_ENDPOINT"],
   deployment_name=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
   model_name="gpt-4",
   api_version="2024-02-15-preview"
)


embeddings = AzureOpenAIEmbeddings(
   azure_endpoint=os.environ["AZURE_ENDPOINT"],
   model="text-embedding-ada-002"
)

在我的示例中,我使用 Azure OpenAI 作为 LLM(gpt-4)以及使用 text-embedding-ada-002 作为嵌入。然而,这应该适用于任何基于云的 LLM 以及像 Llama 3 这样的本地 LLM,甚至适用于我使用 OpenAI 的嵌入模型,因为我们已经在使用 gpt-4。

然后,我们使用元数据定义文档,然后使用已建立的元数据字段将文档索引到 Elasticsearch 中:

# --- Define Metadata Attributes ---
metadata_field_info = [
   AttributeInfo(
       name="year",
       description="The year the movie was released",
       type="integer",
   ),
   AttributeInfo(
       name="rating",
       description="The rating of the movie (out of 10)",
       type="float",
   ),
   AttributeInfo(
       name="genre",
       description="The genre of the movie",
       type="string",
   ),
   AttributeInfo(
       name="director",
       description="The director of the movie",
       type="string",
   ),
   AttributeInfo(
       name="title",
       description="The title of the movie",
       type="string",
   )
]
docs = [
   Document(
       page_content="Following clues to the origin of mankind, a team finds a structure on a distant moon, but they soon realize they are not alone.",
       metadata={"year": 2012, "rating": 7.7, "genre": "science fiction", "title": "Prometheus"},
   ),
...more documents

接下来将它们添加到 Elasticsearch 索引中,es_store.add_embeddings 函数会将文档添加到你在 ELASTIC_INDEX_NAME 变量中选择的索引中,如果在集群中找不到该索引,则会创建具有该名称的索引。在我的示例中,我使用的是 Elastic Cloud 部署,但这也适用于自管理集群:

es_store = ElasticsearchStore(
   es_cloud_id=ELASTIC_CLOUD_ID,
   es_user=ELASTIC_USERNAME,
   es_password=ELASTIC_PASSWORD,
   index_name=ELASTIC_INDEX_NAME,
   embedding=embeddings,
)
es_store.add_embeddings(text_embeddings=list(zip(texts, doc_embeddings)), metadatas=metadatas)

然后创建自查询检索器,接受用户的查询,使用 LLM(我们之前设置的 Azure OpenAI)来解释它,然后构建一个结合语义搜索和元数据过滤器的 Elasticsearch 查询。这一切都由 docs = trieser.invoke(query) 执行:

# --- Create the self-querying Retriever (Using your LLM) ---
retriever = SelfQueryRetriever.from_llm(
   llm,
   es_store,
   "Search for movies",
   metadata_field_info,
   verbose=True,
)
while True:
   # Prompt the user for a query
   query = input("\nEnter your search query (or type 'exit' to quit): ")
   if query.lower() == 'exit':
       break
  
   # Execute the query and print the results
   print(f"\nQuery: {query}")
   docs = retriever.invoke(query)
   print(f"Found {len(docs)} documents:")
   for doc in docs:
       print(doc.page_content)
       print(doc.metadata)
       print("-" * 20)

我们做到了!然后根据 Elasticsearch 索引执行查询,返回与内容和元数据标准最匹配的相关文档。此过程使用户能够进行自然语言查询,如下面的示例所示:

Query: What is a highly rated movie from the 1970s?
Found 3 documents:
The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.
{'year': 1972, 'rating': 9.2, 'genre': 'crime', 'title': 'The Godfather'}
--------------------
Three men walk into the Zone, three men walk out of the Zone
{'year': 1979, 'director': 'Andrei Tarkovsky', 'genre': 'thriller', 'rating': 9.9, 'title': 'Stalker'}
--------------------
Four armed men hijack a New York City subway car and demand a ransom for the passengers
{'year': 1974, 'rating': 7.6, 'director': 'Joseph Sargent', 'genre': 'action', 'title': 'The Taking of Pelham One Two Three'}

结论

虽然自查询检索器提供了一些显著的优势,但必须考虑它们的局限性:

  • 自查询检索器依赖于 LLM 解释用户查询和提取正确的元数据过滤器的准确性。如果查询过于模糊或元数据定义不明确,则检索器可能会产生不正确或不完整的结果。
  • 自查询过程的性能取决于查询的复杂性和数据集的大小。对于极大的数据集或非常复杂的查询,LLM 处理和查询构建可能会带来一些开销。
  • 应该考虑使用 LLM 进行查询解释的成本,尤其是对于高流量应用程序。

尽管存在这些考虑,自查询检索器仍然代表了信息检索的强大增强,尤其是与 Elasticsearch 的可扩展性和强大功能相结合时,为构建搜索 AI 应用程序提供了引人注目的解决方案。

有兴趣自己尝试一下吗?开始免费的云试用并在此处查看示例代码。你对可以在 Elastic Stack 中使用的其他检索器(例如 Reciprocal Rank Fusion)感兴趣吗?请参阅此处的文档以了解更多信息。

Elasticsearch 与行业领先的 Gen AI 工具和提供商进行了原生集成。查看我们的网络研讨会,了解如何超越 RAG 基础知识,或构建可用于生产的应用程序 Elastic Vector Database。

为了为你的用例构建最佳搜索解决方案,请立即开始免费云试用或在您的本地机器上试用 Elastic。

原文:Unleashing your metadata: Self-querying retrievers with Elasticsearch - Elasticsearch Labs

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

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

相关文章

1.14学习总结

日常刷题单 刷了题目后,对于排序方法更加熟练,手搓代码的速度也得到了提高。 感觉字符串还不熟练,高精度更是云里雾里,上升空间极大。 同时看见今晚有个入门难度的测试,去练了练手,想看看自己是什么成分&…

【Prometheus】prometheus黑盒监控balckbox全面解析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

游戏引擎学习第101天

回顾当前情况 昨天的进度基本上完成了所有内容,但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的,但还是存在一些可能或者确定的bug。正如昨天最后提到的,既然现在时间晚了,就不太适合开始调试,所以今天我…

海康摄像头IPV6模式,手动,自动,路由公告

海康摄像头DS-2DC7220IW-A 网络设置中的IPv6配置选项。IPv6是互联网协议(IP)的第六版,用于替代IPv4,提供更多的IP地址和改进的网络功能。图片中的选项允许用户选择如何配置设备的IPv6网络连接: 手动:用户可…

架构设计系列(二):CI/CD

一、概述 CI/CD 是 持续集成(Continuous Integration) 和 持续交付/持续部署(Continuous Delivery/Continuous Deployment) 的缩写,是现代软件开发中的一套核心实践和工具链,旨在提高软件交付的效率、质量…

DDoS技术解析

这里是Themberfue 今天我们不聊别的,我们聊聊著名的网络攻击手段之一的 DDoS,看看其背后的技术细节。 DoS 了解 DDoS 前,先来讲讲 DoS 是什么,此 DoS 而不是 DOS 操作系统啊。1996年9月6日,世界第三古老的网络服务提供…

28 在可以控制 postgres 服务器, 不知道任何用户名的情况下怎 进入 postgres 服务器

前言 最近有这样的一个需求, 有一个 postgres 服务器 但是 不知道 他的任何的用户名密码, 但是我想要查询这台 postgres 服务器 然后 基于这个需求, 我们看一下 怎么来处理 pg_hba.conf 认证方式修改为 trust 首先将 postgres 服务器的认证方式修改为 trust 这时候 …

《图解设计模式》笔记(十)用类来表现

二十二、Command模式:命令也是类 一个类调用某方法,虽然调用结果会反映在对象的状态中,但不会留下工作的历史记录。 若有一个类表示“请进行这项工作”的“命令”,每一项想做的工作就不再是“方法的调用”这种动态处理了,而是一个表示命令的类的实例,即可以用“物”来表…

docker容器部署jar应用导入文件时候报缺少字体错误解决

如题,在导入文件时候报错如下: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager 经查是缺少对应字体,解决办法有两张: 第一种:…

npm安装时无法访问github域名的解决方法

个人博客地址:npm安装时无法访问github域名的解决方法 | 一张假钞的真实世界 今天在用npm install的时候出现了github项目访问不了的异常: npm ERR! Error while executing: npm ERR! /bin/git ls-remote -h -t https://github.com/nhn/raphael.git np…

APP端弱网模拟与网络测试:如何确保应用在各种网络环境下稳定运行

随着智能手机的普及,APP的网络性能成为用户体验的关键因素之一。尤其是在弱网环境下,应用的表现可能严重影响用户的满意度。因此,APP端的网络测试,尤其是弱网模拟,成为了提升产品质量和用户体验的重要环节。 当前APP网…

从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地

导读:日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案,替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度,规模达到…

BFS 走迷宫

#include<bits/stdc.h> using namespace std; int a[100][100],v[100][100];//访问数组 n,m<100 struct point {int x;int y;int step; }; queue<point> r;//申请队列 int dx[4]{0,1,0,-1};//四个方向 右下左上 int dy[4]{1,0,-1,0}; int main() { /* 5 4 1 …

计算机毕业设计SpringBoot+Vue.js医院住院管理系统(源码+lw文档+PPT+讲解视频)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

MongoDB 7 分片副本集升级方案详解(下)

#作者&#xff1a;任少近 文章目录 1.4 分片升级1.5 升级shard11.6 升级shard2,shard31.7 升级mongos1.8重新启用负载均衡器1.9 推荐MongoDB Compass来验证数据 2 注意事项&#xff1a; 1.4 分片升级 使用“滚动”升级从 MongoDB 7.0 升级到 8.0&#xff0c;即在其他成员可用…

【含开题报告+文档+PPT+源码】基于spring boot的固定资产管理系统

开题报告 本研究论文提出了一种基于SpringBoot框架构建的全面且高效的固定资产管理系统&#xff0c;旨在优化企业内部的固定资产全生命周期管理流程。该系统集成了员工权限管理、业务流程处理及数据分析于一体&#xff0c;实现了员工便捷的登录注册功能&#xff0c;并通过安全…

Unity嵌入到Winform

Unity嵌入到Winform Winform工程&#x1f308;

Svelte 最新中文文档翻译(8)—— @html、@const、@debug 模板语法

前言 Svelte&#xff0c;一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte 以其独特的编…

Qt Designer菜鸟使用教程(实现一个本地英文翻译软件)

1 安装Qt Designer 安装这个包的时候会自带安装 Qt Designer, 安装目录为python的安装根目录的 Lib/site-packages/qt5_applications/Qt/bin 目录下。 pip install pyqt5-tools2 新建窗体 2.1 新建主窗体 创建之后如下图&#xff1a; 设置主窗口大小&#xff1a; 设置窗…

CPT205 计算机图形学 OpenGL 3D实践(CW2)

文章目录 1. 介绍2. 设计3. 准备阶段4. 角色构建5. 场景构建6. 交互部分6.1 键盘交互6.2 鼠标交互6.3 鼠标点击出多级菜单进行交互 7. 缺点与问题7.1 程序bug7.2 游戏乐趣不足7.3 画面不够好看 8. 完整代码 1. 介绍 前面已经分享过了关于CPT205的CW1的2D作业&#xff0c;这次C…